aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/cputopology.txt6
-rw-r--r--arch/alpha/kernel/irq.c2
-rw-r--r--arch/arm/kernel/irq.c18
-rw-r--r--arch/arm/kernel/vmlinux.lds.S1
-rw-r--r--arch/arm/mach-imx/clock.c2
-rw-r--r--arch/arm/mach-imx/generic.c6
-rw-r--r--arch/arm/mach-imx/include/mach/imx-regs.h106
-rw-r--r--arch/arm/mach-w90x900/mach-w90p910evb.c1
-rw-r--r--arch/arm/mach-w90x900/time.c1
-rw-r--r--arch/arm/mm/proc-syms.c1
-rw-r--r--arch/arm/oprofile/op_model_mpcore.c2
-rw-r--r--arch/blackfin/kernel/irqchip.c5
-rw-r--r--arch/ia64/kernel/iosapic.c2
-rw-r--r--arch/ia64/kernel/irq.c4
-rw-r--r--arch/ia64/kernel/irq_ia64.c12
-rw-r--r--arch/ia64/kernel/msi_ia64.c4
-rw-r--r--arch/ia64/kernel/vmlinux.lds.S1
-rw-r--r--arch/ia64/sn/kernel/msi_sn.c2
-rw-r--r--arch/m68k/amiga/amiints.c12
-rw-r--r--arch/m68k/amiga/cia.c4
-rw-r--r--arch/m68k/amiga/config.c3
-rw-r--r--arch/m68k/apollo/config.c7
-rw-r--r--arch/m68k/atari/atakeyb.c10
-rw-r--r--arch/m68k/atari/stdma.c5
-rw-r--r--arch/m68k/atari/time.c5
-rw-r--r--arch/m68k/bvme6000/config.c1
-rw-r--r--arch/m68k/hp300/time.c3
-rw-r--r--arch/m68k/kernel/.gitignore1
-rw-r--r--arch/m68k/kernel/entry.S2
-rw-r--r--arch/m68k/kernel/setup.c11
-rw-r--r--arch/m68k/kernel/signal.c15
-rw-r--r--arch/m68k/kernel/vmlinux-sun3.lds1
-rw-r--r--arch/m68k/mac/baboon.c3
-rw-r--r--arch/m68k/mac/config.c12
-rw-r--r--arch/m68k/mac/debug.c1
-rw-r--r--arch/m68k/mac/iop.c10
-rw-r--r--arch/m68k/mac/macints.c15
-rw-r--r--arch/m68k/mac/misc.c1
-rw-r--r--arch/m68k/mac/oss.c25
-rw-r--r--arch/m68k/mac/psc.c12
-rw-r--r--arch/m68k/mac/via.c35
-rw-r--r--arch/m68k/math-emu/fp_log.c1
-rw-r--r--arch/m68k/mm/init.c4
-rw-r--r--arch/m68k/mm/motorola.c7
-rw-r--r--arch/m68k/mvme147/config.c6
-rw-r--r--arch/m68k/mvme16x/config.c1
-rw-r--r--arch/m68k/q40/config.c3
-rw-r--r--arch/m68k/sun3/config.c8
-rw-r--r--arch/m68k/sun3/mmu_emu.c1
-rw-r--r--arch/m68k/sun3/sun3ints.c9
-rw-r--r--arch/m68k/sun3x/config.c1
-rw-r--r--arch/mips/Kconfig71
-rw-r--r--arch/mips/Makefile40
-rw-r--r--arch/mips/alchemy/Kconfig5
-rw-r--r--arch/mips/alchemy/common/Makefile4
-rw-r--r--arch/mips/alchemy/common/au1xxx_irqmap.c205
-rw-r--r--arch/mips/alchemy/common/clocks.c65
-rw-r--r--arch/mips/alchemy/common/cputable.c52
-rw-r--r--arch/mips/alchemy/common/dbdma.c65
-rw-r--r--arch/mips/alchemy/common/irq.c745
-rw-r--r--arch/mips/alchemy/common/power.c406
-rw-r--r--arch/mips/alchemy/common/reset.c2
-rw-r--r--arch/mips/alchemy/common/setup.c71
-rw-r--r--arch/mips/alchemy/common/sleeper.S118
-rw-r--r--arch/mips/alchemy/common/time.c311
-rw-r--r--arch/mips/alchemy/db1x00/init.c62
-rw-r--r--arch/mips/alchemy/devboards/Makefile18
-rw-r--r--arch/mips/alchemy/devboards/db1x00/Makefile (renamed from arch/mips/alchemy/db1x00/Makefile)2
-rw-r--r--arch/mips/alchemy/devboards/db1x00/board_setup.c (renamed from arch/mips/alchemy/db1x00/board_setup.c)37
-rw-r--r--arch/mips/alchemy/devboards/db1x00/irqmap.c (renamed from arch/mips/alchemy/db1x00/irqmap.c)24
-rw-r--r--arch/mips/alchemy/devboards/pb1000/Makefile (renamed from arch/mips/alchemy/pb1000/Makefile)2
-rw-r--r--arch/mips/alchemy/devboards/pb1000/board_setup.c (renamed from arch/mips/alchemy/pb1000/board_setup.c)30
-rw-r--r--arch/mips/alchemy/devboards/pb1100/Makefile (renamed from arch/mips/alchemy/pb1100/Makefile)2
-rw-r--r--arch/mips/alchemy/devboards/pb1100/board_setup.c (renamed from arch/mips/alchemy/pb1100/board_setup.c)47
-rw-r--r--arch/mips/alchemy/devboards/pb1200/Makefile (renamed from arch/mips/alchemy/pb1200/Makefile)3
-rw-r--r--arch/mips/alchemy/devboards/pb1200/board_setup.c (renamed from arch/mips/alchemy/pb1200/board_setup.c)34
-rw-r--r--arch/mips/alchemy/devboards/pb1200/irqmap.c (renamed from arch/mips/alchemy/pb1200/irqmap.c)94
-rw-r--r--arch/mips/alchemy/devboards/pb1200/platform.c (renamed from arch/mips/alchemy/pb1200/platform.c)0
-rw-r--r--arch/mips/alchemy/devboards/pb1500/Makefile (renamed from arch/mips/alchemy/pb1500/Makefile)2
-rw-r--r--arch/mips/alchemy/devboards/pb1500/board_setup.c (renamed from arch/mips/alchemy/pb1500/board_setup.c)44
-rw-r--r--arch/mips/alchemy/devboards/pb1550/Makefile (renamed from arch/mips/alchemy/pb1550/Makefile)2
-rw-r--r--arch/mips/alchemy/devboards/pb1550/board_setup.c (renamed from arch/mips/alchemy/pb1550/board_setup.c)34
-rw-r--r--arch/mips/alchemy/devboards/pm.c229
-rw-r--r--arch/mips/alchemy/devboards/prom.c (renamed from arch/mips/alchemy/pb1550/init.c)26
-rw-r--r--arch/mips/alchemy/mtx-1/board_setup.c12
-rw-r--r--arch/mips/alchemy/mtx-1/init.c2
-rw-r--r--arch/mips/alchemy/mtx-1/irqmap.c18
-rw-r--r--arch/mips/alchemy/pb1000/init.c57
-rw-r--r--arch/mips/alchemy/pb1000/irqmap.c38
-rw-r--r--arch/mips/alchemy/pb1100/init.c60
-rw-r--r--arch/mips/alchemy/pb1100/irqmap.c40
-rw-r--r--arch/mips/alchemy/pb1200/init.c58
-rw-r--r--arch/mips/alchemy/pb1500/init.c58
-rw-r--r--arch/mips/alchemy/pb1500/irqmap.c46
-rw-r--r--arch/mips/alchemy/pb1550/irqmap.c43
-rw-r--r--arch/mips/alchemy/xxs1500/board_setup.c12
-rw-r--r--arch/mips/alchemy/xxs1500/init.c2
-rw-r--r--arch/mips/alchemy/xxs1500/irqmap.c31
-rw-r--r--arch/mips/cavium-octeon/Kconfig85
-rw-r--r--arch/mips/cavium-octeon/Makefile16
-rw-r--r--arch/mips/cavium-octeon/csrc-octeon.c58
-rw-r--r--arch/mips/cavium-octeon/dma-octeon.c32
-rw-r--r--arch/mips/cavium-octeon/executive/Makefile13
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-bootmem.c586
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-l2c.c734
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-sysinfo.c116
-rw-r--r--arch/mips/cavium-octeon/executive/octeon-model.c358
-rw-r--r--arch/mips/cavium-octeon/flash_setup.c84
-rw-r--r--arch/mips/cavium-octeon/octeon-irq.c497
-rw-r--r--arch/mips/cavium-octeon/octeon-memcpy.S521
-rw-r--r--arch/mips/cavium-octeon/serial.c136
-rw-r--r--arch/mips/cavium-octeon/setup.c929
-rw-r--r--arch/mips/cavium-octeon/smp.c211
-rw-r--r--arch/mips/configs/cavium-octeon_defconfig943
-rw-r--r--arch/mips/include/asm/cpu-features.h3
-rw-r--r--arch/mips/include/asm/cpu.h14
-rw-r--r--arch/mips/include/asm/hazards.h4
-rw-r--r--arch/mips/include/asm/io.h14
-rw-r--r--arch/mips/include/asm/irq.h2
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1000.h89
-rw-r--r--arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h5
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h78
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h64
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/irq.h244
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h131
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/war.h26
-rw-r--r--arch/mips/include/asm/mach-generic/dma-coherence.h26
-rw-r--r--arch/mips/include/asm/mach-ip27/dma-coherence.h26
-rw-r--r--arch/mips/include/asm/mach-ip32/dma-coherence.h26
-rw-r--r--arch/mips/include/asm/mach-jazz/dma-coherence.h26
-rw-r--r--arch/mips/include/asm/mach-lemote/dma-coherence.h26
-rw-r--r--arch/mips/include/asm/mipsregs.h22
-rw-r--r--arch/mips/include/asm/module.h2
-rw-r--r--arch/mips/include/asm/octeon/cvmx-asm.h128
-rw-r--r--arch/mips/include/asm/octeon/cvmx-bootinfo.h262
-rw-r--r--arch/mips/include/asm/octeon/cvmx-bootmem.h288
-rw-r--r--arch/mips/include/asm/octeon/cvmx-ciu-defs.h1616
-rw-r--r--arch/mips/include/asm/octeon/cvmx-gpio-defs.h219
-rw-r--r--arch/mips/include/asm/octeon/cvmx-iob-defs.h530
-rw-r--r--arch/mips/include/asm/octeon/cvmx-ipd-defs.h877
-rw-r--r--arch/mips/include/asm/octeon/cvmx-l2c-defs.h963
-rw-r--r--arch/mips/include/asm/octeon/cvmx-l2c.h325
-rw-r--r--arch/mips/include/asm/octeon/cvmx-l2d-defs.h369
-rw-r--r--arch/mips/include/asm/octeon/cvmx-l2t-defs.h141
-rw-r--r--arch/mips/include/asm/octeon/cvmx-led-defs.h240
-rw-r--r--arch/mips/include/asm/octeon/cvmx-mio-defs.h2004
-rw-r--r--arch/mips/include/asm/octeon/cvmx-packet.h61
-rw-r--r--arch/mips/include/asm/octeon/cvmx-pow-defs.h698
-rw-r--r--arch/mips/include/asm/octeon/cvmx-spinlock.h232
-rw-r--r--arch/mips/include/asm/octeon/cvmx-sysinfo.h152
-rw-r--r--arch/mips/include/asm/octeon/cvmx.h505
-rw-r--r--arch/mips/include/asm/octeon/octeon-feature.h119
-rw-r--r--arch/mips/include/asm/octeon/octeon-model.h321
-rw-r--r--arch/mips/include/asm/octeon/octeon.h248
-rw-r--r--arch/mips/include/asm/processor.h69
-rw-r--r--arch/mips/include/asm/ptrace.h4
-rw-r--r--arch/mips/include/asm/smp.h3
-rw-r--r--arch/mips/include/asm/stackframe.h17
-rw-r--r--arch/mips/include/asm/time.h24
-rw-r--r--arch/mips/kernel/Makefile5
-rw-r--r--arch/mips/kernel/asm-offsets.c31
-rw-r--r--arch/mips/kernel/branch.c33
-rw-r--r--arch/mips/kernel/cevt-r4k.c2
-rw-r--r--arch/mips/kernel/cpu-probe.c31
-rw-r--r--arch/mips/kernel/csrc-r4k.c2
-rw-r--r--arch/mips/kernel/genex.S4
-rw-r--r--arch/mips/kernel/irq-gic.c2
-rw-r--r--arch/mips/kernel/irq.c1
-rw-r--r--arch/mips/kernel/octeon_switch.S506
-rw-r--r--arch/mips/kernel/ptrace32.c64
-rw-r--r--arch/mips/kernel/smtc.c6
-rw-r--r--arch/mips/kernel/traps.c21
-rw-r--r--arch/mips/lib/Makefile1
-rw-r--r--arch/mips/mm/Makefile1
-rw-r--r--arch/mips/mm/c-octeon.c307
-rw-r--r--arch/mips/mm/cache.c6
-rw-r--r--arch/mips/mm/cex-oct.S70
-rw-r--r--arch/mips/mm/dma-default.c25
-rw-r--r--arch/mips/mm/tlb-r4k.c5
-rw-r--r--arch/mips/mm/tlbex.c1
-rw-r--r--arch/mips/mti-malta/malta-smtc.c5
-rw-r--r--arch/mips/sgi-ip22/ip22-int.c2
-rw-r--r--arch/mips/sgi-ip22/ip22-time.c2
-rw-r--r--arch/mips/sibyte/bcm1480/smp.c3
-rw-r--r--arch/mips/sibyte/sb1250/smp.c3
-rw-r--r--arch/mn10300/kernel/mn10300-watchdog.c3
-rw-r--r--arch/parisc/kernel/irq.c8
-rw-r--r--arch/powerpc/boot/dts/gef_sbc610.dts15
-rw-r--r--arch/powerpc/configs/86xx/gef_sbc610_defconfig1
-rw-r--r--arch/powerpc/kernel/irq.c2
-rw-r--r--arch/powerpc/kernel/vmlinux.lds.S1
-rw-r--r--arch/powerpc/platforms/cell/cbe_cpufreq.c2
-rw-r--r--arch/powerpc/platforms/cell/cpufreq_spudemand.c4
-rw-r--r--arch/powerpc/platforms/pasemi/cpufreq.c2
-rw-r--r--arch/powerpc/platforms/powermac/cpufreq_64.c2
-rw-r--r--arch/powerpc/platforms/pseries/xics.c5
-rw-r--r--arch/powerpc/sysdev/mpic.c3
-rw-r--r--arch/sparc/configs/sparc32_defconfig290
-rw-r--r--arch/sparc/include/asm/oplib_32.h11
-rw-r--r--arch/sparc/include/asm/oplib_64.h10
-rw-r--r--arch/sparc/include/asm/signal.h4
-rw-r--r--arch/sparc/include/asm/topology_64.h4
-rw-r--r--arch/sparc/kernel/auxio_32.c3
-rw-r--r--arch/sparc/kernel/auxio_64.c2
-rw-r--r--arch/sparc/kernel/cpu.c2
-rw-r--r--arch/sparc/kernel/idprom.c3
-rw-r--r--arch/sparc/kernel/ioport.c15
-rw-r--r--arch/sparc/kernel/irq_32.c1
-rw-r--r--arch/sparc/kernel/irq_64.c5
-rw-r--r--arch/sparc/kernel/pci.c1
-rw-r--r--arch/sparc/kernel/pcic.c6
-rw-r--r--arch/sparc/kernel/process_32.c2
-rw-r--r--arch/sparc/kernel/process_64.c2
-rw-r--r--arch/sparc/kernel/psycho_common.c60
-rw-r--r--arch/sparc/kernel/sbus.c1
-rw-r--r--arch/sparc/kernel/setup_32.c3
-rw-r--r--arch/sparc/kernel/setup_64.c3
-rw-r--r--arch/sparc/kernel/sparc_ksyms_32.c225
-rw-r--r--arch/sparc/kernel/sparc_ksyms_64.c243
-rw-r--r--arch/sparc/kernel/sun4d_smp.c4
-rw-r--r--arch/sparc/kernel/sys_sparc_64.c2
-rw-r--r--arch/sparc/kernel/time_32.c2
-rw-r--r--arch/sparc/kernel/time_64.c4
-rw-r--r--arch/sparc/kernel/traps_32.c1
-rw-r--r--arch/sparc/kernel/traps_64.c2
-rw-r--r--arch/sparc/kernel/unaligned_64.c8
-rw-r--r--arch/sparc/lib/Makefile1
-rw-r--r--arch/sparc/lib/PeeCeeI.c8
-rw-r--r--arch/sparc/lib/ksyms.c196
-rw-r--r--arch/sparc/lib/user_fixup.c5
-rw-r--r--arch/sparc/mm/generic_32.c1
-rw-r--r--arch/sparc/mm/generic_64.c1
-rw-r--r--arch/sparc/mm/highmem.c2
-rw-r--r--arch/sparc/mm/init_32.c6
-rw-r--r--arch/sparc/mm/init_64.c4
-rw-r--r--arch/sparc/prom/init_32.c4
-rw-r--r--arch/sparc/prom/misc_32.c3
-rw-r--r--arch/sparc/prom/misc_64.c3
-rw-r--r--arch/sparc/prom/ranges.c3
-rw-r--r--arch/sparc/prom/tree_32.c17
-rw-r--r--arch/sparc/prom/tree_64.c18
-rw-r--r--arch/x86/ia32/ia32entry.S8
-rw-r--r--arch/x86/include/asm/apicnum.h12
-rw-r--r--arch/x86/include/asm/bitops.h14
-rw-r--r--arch/x86/include/asm/cpu.h21
-rw-r--r--arch/x86/include/asm/cpumask.h28
-rw-r--r--arch/x86/include/asm/current.h24
-rw-r--r--arch/x86/include/asm/hardirq_32.h3
-rw-r--r--arch/x86/include/asm/hardirq_64.h25
-rw-r--r--arch/x86/include/asm/io_apic.h26
-rw-r--r--arch/x86/include/asm/irq_regs_32.h4
-rw-r--r--arch/x86/include/asm/irq_vectors.h13
-rw-r--r--arch/x86/include/asm/mach-default/mach_wakecpu.h6
-rw-r--r--arch/x86/include/asm/mmu_context_32.h12
-rw-r--r--arch/x86/include/asm/mmu_context_64.h16
-rw-r--r--arch/x86/include/asm/mpspec_def.h23
-rw-r--r--arch/x86/include/asm/mtrr.h10
-rw-r--r--arch/x86/include/asm/page_64.h4
-rw-r--r--arch/x86/include/asm/paravirt.h8
-rw-r--r--arch/x86/include/asm/pda.h125
-rw-r--r--arch/x86/include/asm/percpu.h159
-rw-r--r--arch/x86/include/asm/pgtable.h19
-rw-r--r--arch/x86/include/asm/processor.h3
-rw-r--r--arch/x86/include/asm/setup.h1
-rw-r--r--arch/x86/include/asm/smp.h49
-rw-r--r--arch/x86/include/asm/system.h4
-rw-r--r--arch/x86/include/asm/thread_info.h20
-rw-r--r--arch/x86/include/asm/tlbflush.h17
-rw-r--r--arch/x86/include/asm/topology.h8
-rw-r--r--arch/x86/include/asm/trampoline.h1
-rw-r--r--arch/x86/include/asm/uv/uv_bau.h3
-rw-r--r--arch/x86/kernel/acpi/boot.c96
-rw-r--r--arch/x86/kernel/acpi/sleep.c1
-rw-r--r--arch/x86/kernel/apic.c25
-rw-r--r--arch/x86/kernel/asm-offsets_64.c8
-rw-r--r--arch/x86/kernel/cpu/common.c80
-rw-r--r--arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c27
-rw-r--r--arch/x86/kernel/cpu/intel_cacheinfo.c63
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_amd_64.c21
-rw-r--r--arch/x86/kernel/crash.c2
-rw-r--r--arch/x86/kernel/dumpstack_64.c35
-rw-r--r--arch/x86/kernel/entry_32.S2
-rw-r--r--arch/x86/kernel/entry_64.S41
-rw-r--r--arch/x86/kernel/head64.c23
-rw-r--r--arch/x86/kernel/head_64.S47
-rw-r--r--arch/x86/kernel/io_apic.c163
-rw-r--r--arch/x86/kernel/irq.c6
-rw-r--r--arch/x86/kernel/irq_32.c2
-rw-r--r--arch/x86/kernel/irq_64.c5
-rw-r--r--arch/x86/kernel/microcode_intel.c10
-rw-r--r--arch/x86/kernel/module_32.c6
-rw-r--r--arch/x86/kernel/module_64.c32
-rw-r--r--arch/x86/kernel/mpparse.c143
-rw-r--r--arch/x86/kernel/msr.c2
-rw-r--r--arch/x86/kernel/nmi.c10
-rw-r--r--arch/x86/kernel/process_32.c5
-rw-r--r--arch/x86/kernel/process_64.c22
-rw-r--r--arch/x86/kernel/reboot.c1
-rw-r--r--arch/x86/kernel/setup.c2
-rw-r--r--arch/x86/kernel/setup_percpu.c208
-rw-r--r--arch/x86/kernel/smpboot.c69
-rw-r--r--arch/x86/kernel/smpcommon.c10
-rw-r--r--arch/x86/kernel/tlb_32.c85
-rw-r--r--arch/x86/kernel/tlb_64.c76
-rw-r--r--arch/x86/kernel/tlb_uv.c16
-rw-r--r--arch/x86/kernel/vmlinux_32.lds.S9
-rw-r--r--arch/x86/kernel/vmlinux_64.lds.S22
-rw-r--r--arch/x86/kernel/x8664_ksyms_64.c2
-rw-r--r--arch/x86/mach-voyager/setup.c1
-rw-r--r--arch/x86/mach-voyager/voyager_smp.c6
-rw-r--r--arch/x86/mm/fault.c2
-rw-r--r--arch/x86/mm/init_32.c1
-rw-r--r--arch/x86/mm/pageattr.c10
-rw-r--r--arch/x86/mm/pat.c127
-rw-r--r--arch/x86/pci/i386.c12
-rw-r--r--arch/x86/xen/enlighten.c47
-rw-r--r--arch/x86/xen/irq.c8
-rw-r--r--arch/x86/xen/mmu.c8
-rw-r--r--arch/x86/xen/multicalls.h2
-rw-r--r--arch/x86/xen/smp.c33
-rw-r--r--arch/x86/xen/xen-asm_64.S31
-rw-r--r--drivers/ata/libata-sff.c9
-rw-r--r--drivers/ata/pata_it821x.c17
-rw-r--r--drivers/base/cpu.c2
-rw-r--r--drivers/base/topology.c33
-rw-r--r--drivers/block/amiflop.c40
-rw-r--r--drivers/char/amiserial.c36
-rw-r--r--drivers/char/pty.c4
-rw-r--r--drivers/char/ser_a2232.c12
-rw-r--r--drivers/char/vme_scc.c166
-rw-r--r--drivers/dio/dio-sysfs.c19
-rw-r--r--drivers/dio/dio.c18
-rw-r--r--drivers/firmware/dcdbas.c12
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c2
-rw-r--r--drivers/infiniband/hw/mlx4/main.c13
-rw-r--r--drivers/infiniband/hw/nes/nes_cm.c12
-rw-r--r--drivers/infiniband/hw/nes/nes_utils.c4
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c38
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c3
-rw-r--r--drivers/infiniband/ulp/iser/Kconfig2
-rw-r--r--drivers/input/misc/Kconfig7
-rw-r--r--drivers/input/misc/Makefile1
-rw-r--r--drivers/input/misc/pcf50633-input.c132
-rw-r--r--drivers/isdn/hardware/mISDN/hfcmulti.c3
-rw-r--r--drivers/isdn/hardware/mISDN/hfcpci.c2
-rw-r--r--drivers/isdn/mISDN/dsp_cmx.c5
-rw-r--r--drivers/isdn/mISDN/dsp_pipeline.c4
-rw-r--r--drivers/mfd/Kconfig23
-rw-r--r--drivers/mfd/Makefile4
-rw-r--r--drivers/mfd/dm355evm_msp.c10
-rw-r--r--drivers/mfd/pcf50633-adc.c277
-rw-r--r--drivers/mfd/pcf50633-core.c710
-rw-r--r--drivers/mfd/pcf50633-gpio.c118
-rw-r--r--drivers/mfd/sm501.c30
-rw-r--r--drivers/mfd/twl4030-core.c11
-rw-r--r--drivers/misc/sgi-xp/xpc_main.c2
-rw-r--r--drivers/net/3c503.c1
-rw-r--r--drivers/net/3c59x.c2
-rw-r--r--drivers/net/8139cp.c2
-rw-r--r--drivers/net/8139too.c2
-rw-r--r--drivers/net/8390.c1
-rw-r--r--drivers/net/8390p.c1
-rw-r--r--drivers/net/Kconfig2
-rw-r--r--drivers/net/acenic.c1
-rw-r--r--drivers/net/arm/etherh.c1
-rw-r--r--drivers/net/arm/ks8695net.c1
-rw-r--r--drivers/net/b44.c13
-rw-r--r--drivers/net/cxgb3/adapter.h7
-rw-r--r--drivers/net/cxgb3/cxgb3_main.c22
-rw-r--r--drivers/net/cxgb3/sge.c2
-rw-r--r--drivers/net/e1000e/ich8lan.c19
-rw-r--r--drivers/net/e2100.c1
-rw-r--r--drivers/net/enic/enic_main.c1
-rw-r--r--drivers/net/forcedeth.c22
-rw-r--r--drivers/net/gianfar.c15
-rw-r--r--drivers/net/hamachi.c1
-rw-r--r--drivers/net/hamradio/6pack.c3
-rw-r--r--drivers/net/hp-plus.c1
-rw-r--r--drivers/net/hydra.c1
-rw-r--r--drivers/net/irda/au1k_ir.c2
-rw-r--r--drivers/net/irda/donauboe.c8
-rw-r--r--drivers/net/mac8390.c1
-rw-r--r--drivers/net/mlx4/en_netdev.c1
-rw-r--r--drivers/net/mlx4/main.c4
-rw-r--r--drivers/net/ne-h8300.c1
-rw-r--r--drivers/net/ne2k-pci.c1
-rw-r--r--drivers/net/ns83820.c1
-rw-r--r--drivers/net/qlge/qlge.h61
-rw-r--r--drivers/net/qlge/qlge_dbg.c62
-rw-r--r--drivers/net/qlge/qlge_main.c80
-rw-r--r--drivers/net/r6040.c43
-rw-r--r--drivers/net/sc92031.c1
-rw-r--r--drivers/net/sfc/efx.c17
-rw-r--r--drivers/net/sfc/tenxpress.c5
-rw-r--r--drivers/net/sis900.c1
-rw-r--r--drivers/net/smc-mca.c1
-rw-r--r--drivers/net/smc-ultra.c1
-rw-r--r--drivers/net/smsc911x.c4
-rw-r--r--drivers/net/smsc9420.c1
-rw-r--r--drivers/net/ucc_geth.c128
-rw-r--r--drivers/net/ucc_geth.h114
-rw-r--r--drivers/net/via-rhine.c1
-rw-r--r--drivers/net/via-velocity.c1
-rw-r--r--drivers/net/wd.c1
-rw-r--r--drivers/net/wireless/libertas/main.c7
-rw-r--r--drivers/net/yellowfin.c1
-rw-r--r--drivers/net/zorro8390.c1
-rw-r--r--drivers/oprofile/buffer_sync.c22
-rw-r--r--drivers/oprofile/buffer_sync.h4
-rw-r--r--drivers/oprofile/oprof.c9
-rw-r--r--drivers/parisc/superio.c1
-rw-r--r--drivers/pci/intel-iommu.c3
-rw-r--r--drivers/pci/intr_remapping.c1
-rw-r--r--drivers/power/Kconfig6
-rw-r--r--drivers/power/Makefile1
-rw-r--r--drivers/power/pcf50633-charger.c358
-rw-r--r--drivers/regulator/Kconfig7
-rw-r--r--drivers/regulator/Makefile1
-rw-r--r--drivers/regulator/pcf50633-regulator.c329
-rw-r--r--drivers/rtc/Kconfig7
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/rtc-pcf50633.c344
-rw-r--r--drivers/s390/net/qeth_l2_main.c2
-rw-r--r--drivers/s390/net/qeth_l3_main.c24
-rw-r--r--drivers/serial/8250.c2
-rw-r--r--drivers/serial/jsm/jsm_neo.c3
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c73
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.h8
-rw-r--r--drivers/usb/serial/usb-serial.c3
-rw-r--r--drivers/video/Makefile4
-rw-r--r--drivers/video/amifb.c6
-rw-r--r--drivers/video/atafb.c112
-rw-r--r--drivers/video/c2p.c232
-rw-r--r--drivers/video/c2p.h11
-rw-r--r--drivers/video/c2p_core.h153
-rw-r--r--drivers/video/c2p_iplan2.c153
-rw-r--r--drivers/video/c2p_planar.c156
-rw-r--r--drivers/video/console/fbcon.c38
-rw-r--r--drivers/watchdog/Kconfig14
-rw-r--r--drivers/watchdog/Makefile2
-rw-r--r--drivers/watchdog/gef_wdt.c330
-rw-r--r--drivers/watchdog/pika_wdt.c301
-rw-r--r--drivers/watchdog/wm8350_wdt.c6
-rw-r--r--drivers/xen/events.c26
-rw-r--r--drivers/xen/manage.c2
-rw-r--r--drivers/zorro/.gitignore2
-rw-r--r--drivers/zorro/zorro-sysfs.c20
-rw-r--r--drivers/zorro/zorro.c23
-rw-r--r--drivers/zorro/zorro.h2
-rw-r--r--firmware/Makefile3
-rw-r--r--firmware/WHENCE16
-rw-r--r--firmware/mts_cdma.fw.ihex867
-rw-r--r--firmware/mts_edge.fw.ihex881
-rw-r--r--firmware/mts_gsm.fw.ihex867
-rw-r--r--fs/dlm/debug_fs.c696
-rw-r--r--fs/dlm/dlm_internal.h2
-rw-r--r--fs/dlm/lock.c26
-rw-r--r--fs/dlm/lockspace.c2
-rw-r--r--fs/dlm/recover.c10
-rw-r--r--fs/select.c2
-rw-r--r--include/asm-generic/bitops/__ffs.h2
-rw-r--r--include/asm-generic/bitops/__fls.h2
-rw-r--r--include/asm-generic/bitops/fls.h2
-rw-r--r--include/asm-generic/bitops/fls64.h4
-rw-r--r--include/asm-generic/percpu.h52
-rw-r--r--include/asm-generic/pgtable.h4
-rw-r--r--include/asm-generic/sections.h2
-rw-r--r--include/asm-generic/vmlinux.lds.h75
-rw-r--r--include/asm-m68k/unistd.h4
-rw-r--r--include/linux/dio.h2
-rw-r--r--include/linux/dmaengine.h10
-rw-r--r--include/linux/interrupt.h1
-rw-r--r--include/linux/irq.h86
-rw-r--r--include/linux/irqnr.h1
-rw-r--r--include/linux/mISDNif.h5
-rw-r--r--include/linux/mfd/pcf50633/adc.h72
-rw-r--r--include/linux/mfd/pcf50633/core.h218
-rw-r--r--include/linux/mfd/pcf50633/gpio.h52
-rw-r--r--include/linux/mfd/pcf50633/mbc.h134
-rw-r--r--include/linux/mfd/pcf50633/pmic.h67
-rw-r--r--include/linux/smp.h13
-rw-r--r--include/linux/topology.h6
-rw-r--r--include/net/wimax.h4
-rw-r--r--include/sound/soc-dapm.h2
-rw-r--r--include/sound/soc.h15
-rw-r--r--kernel/Makefile6
-rw-r--r--kernel/async.c21
-rw-r--r--kernel/irq/chip.c5
-rw-r--r--kernel/irq/handle.c57
-rw-r--r--kernel/irq/internals.h7
-rw-r--r--kernel/irq/manage.c12
-rw-r--r--kernel/irq/migration.c12
-rw-r--r--kernel/irq/numa_migrate.c19
-rw-r--r--kernel/irq/proc.c4
-rw-r--r--kernel/rcutorture.c113
-rw-r--r--kernel/sched.c13
-rw-r--r--kernel/sched_debug.c21
-rw-r--r--kernel/sched_rt.c36
-rw-r--r--kernel/softirq.c5
-rw-r--r--kernel/up.c21
-rw-r--r--lib/smp_processor_id.c2
-rw-r--r--mm/memory.c24
-rw-r--r--net/bridge/netfilter/ebtables.c3
-rw-r--r--net/core/dev.c13
-rw-r--r--net/dccp/ccids/Kconfig2
-rw-r--r--net/dccp/ccids/lib/tfrc.c2
-rw-r--r--net/tipc/bcast.h2
-rw-r--r--net/xfrm/xfrm_ipcomp.c1
-rw-r--r--scripts/markup_oops.pl59
-rw-r--r--sound/oss/dmasound/dmasound_atari.c5
-rw-r--r--sound/oss/dmasound/dmasound_q40.c16
-rw-r--r--sound/pci/hda/hda_beep.c1
-rw-r--r--sound/pci/hda/hda_codec.c48
-rw-r--r--sound/pci/hda/hda_codec.h2
-rw-r--r--sound/pci/hda/hda_intel.c6
-rw-r--r--sound/pci/hda/patch_analog.c5
-rw-r--r--sound/pci/hda/patch_nvhdmi.c2
-rw-r--r--sound/pci/hda/patch_realtek.c18
-rw-r--r--sound/soc/codecs/twl4030.c12
-rw-r--r--sound/soc/soc-core.c37
-rw-r--r--sound/soc/soc-dapm.c80
-rw-r--r--sound/usb/caiaq/caiaq-device.c2
-rw-r--r--sound/usb/caiaq/caiaq-device.h1
-rw-r--r--sound/usb/caiaq/caiaq-midi.c32
524 files changed, 29464 insertions, 5736 deletions
diff --git a/Documentation/cputopology.txt b/Documentation/cputopology.txt
index 45932ec..b41f3e5 100644
--- a/Documentation/cputopology.txt
+++ b/Documentation/cputopology.txt
@@ -18,11 +18,11 @@ For an architecture to support this feature, it must define some of
these macros in include/asm-XXX/topology.h:
#define topology_physical_package_id(cpu)
#define topology_core_id(cpu)
-#define topology_thread_siblings(cpu)
-#define topology_core_siblings(cpu)
+#define topology_thread_cpumask(cpu)
+#define topology_core_cpumask(cpu)
The type of **_id is int.
-The type of siblings is cpumask_t.
+The type of siblings is (const) struct cpumask *.
To be consistent on all architectures, include/linux/topology.h
provides default definitions for any of the above macros that are
diff --git a/arch/alpha/kernel/irq.c b/arch/alpha/kernel/irq.c
index 703731a..7bc7489 100644
--- a/arch/alpha/kernel/irq.c
+++ b/arch/alpha/kernel/irq.c
@@ -55,7 +55,7 @@ int irq_select_affinity(unsigned int irq)
cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0);
last_cpu = cpu;
- irq_desc[irq].affinity = cpumask_of_cpu(cpu);
+ cpumask_copy(irq_desc[irq].affinity, cpumask_of(cpu));
irq_desc[irq].chip->set_affinity(irq, cpumask_of(cpu));
return 0;
}
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index 7141cee..4bb723e 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -104,6 +104,11 @@ static struct irq_desc bad_irq_desc = {
.lock = SPIN_LOCK_UNLOCKED
};
+#ifdef CONFIG_CPUMASK_OFFSTACK
+/* We are not allocating bad_irq_desc.affinity or .pending_mask */
+#error "ARM architecture does not support CONFIG_CPUMASK_OFFSTACK."
+#endif
+
/*
* do_IRQ handles all hardware IRQ's. Decoded IRQs should not
* come via this function. Instead, they should provide their
@@ -161,7 +166,7 @@ void __init init_IRQ(void)
irq_desc[irq].status |= IRQ_NOREQUEST | IRQ_NOPROBE;
#ifdef CONFIG_SMP
- bad_irq_desc.affinity = CPU_MASK_ALL;
+ cpumask_setall(bad_irq_desc.affinity);
bad_irq_desc.cpu = smp_processor_id();
#endif
init_arch_irq();
@@ -191,15 +196,16 @@ void migrate_irqs(void)
struct irq_desc *desc = irq_desc + i;
if (desc->cpu == cpu) {
- unsigned int newcpu = any_online_cpu(desc->affinity);
-
- if (newcpu == NR_CPUS) {
+ unsigned int newcpu = cpumask_any_and(desc->affinity,
+ cpu_online_mask);
+ if (newcpu >= nr_cpu_ids) {
if (printk_ratelimit())
printk(KERN_INFO "IRQ%u no longer affine to CPU%u\n",
i, cpu);
- cpus_setall(desc->affinity);
- newcpu = any_online_cpu(desc->affinity);
+ cpumask_setall(desc->affinity);
+ newcpu = cpumask_any_and(desc->affinity,
+ cpu_online_mask);
}
route_irq(desc, i, newcpu);
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
index 0021607..85598f7 100644
--- a/arch/arm/kernel/vmlinux.lds.S
+++ b/arch/arm/kernel/vmlinux.lds.S
@@ -65,6 +65,7 @@ SECTIONS
#endif
. = ALIGN(4096);
__per_cpu_start = .;
+ *(.data.percpu.page_aligned)
*(.data.percpu)
*(.data.percpu.shared_aligned)
__per_cpu_end = .;
diff --git a/arch/arm/mach-imx/clock.c b/arch/arm/mach-imx/clock.c
index 7ec60fc..cf332ae 100644
--- a/arch/arm/mach-imx/clock.c
+++ b/arch/arm/mach-imx/clock.c
@@ -23,7 +23,7 @@
#include <linux/err.h>
#include <linux/io.h>
-#include <mach/imx-regs.h>
+#include <mach/hardware.h>
/*
* Very simple approach: We can't disable clocks, so we do
diff --git a/arch/arm/mach-imx/generic.c b/arch/arm/mach-imx/generic.c
index fa72174..887cb21 100644
--- a/arch/arm/mach-imx/generic.c
+++ b/arch/arm/mach-imx/generic.c
@@ -245,11 +245,11 @@ void __init imx_set_mmc_info(struct imxmmc_platform_data *info)
imx_mmc_device.dev.platform_data = info;
}
-static struct imxfb_mach_info imx_fb_info;
+static struct imx_fb_platform_data imx_fb_info;
-void __init set_imx_fb_info(struct imxfb_mach_info *hard_imx_fb_info)
+void __init set_imx_fb_info(struct imx_fb_platform_data *hard_imx_fb_info)
{
- memcpy(&imx_fb_info,hard_imx_fb_info,sizeof(struct imxfb_mach_info));
+ memcpy(&imx_fb_info,hard_imx_fb_info,sizeof(struct imx_fb_platform_data));
}
static struct resource imxfb_resources[] = {
diff --git a/arch/arm/mach-imx/include/mach/imx-regs.h b/arch/arm/mach-imx/include/mach/imx-regs.h
index fb9de27..490297f 100644
--- a/arch/arm/mach-imx/include/mach/imx-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx-regs.h
@@ -373,110 +373,4 @@
#define TSTAT_CAPT (1<<1)
#define TSTAT_COMP (1<<0)
-/*
- * LCD Controller
- */
-
-#define LCDC_SSA __REG(IMX_LCDC_BASE+0x00)
-
-#define LCDC_SIZE __REG(IMX_LCDC_BASE+0x04)
-#define SIZE_XMAX(x) ((((x) >> 4) & 0x3f) << 20)
-#define SIZE_YMAX(y) ( (y) & 0x1ff )
-
-#define LCDC_VPW __REG(IMX_LCDC_BASE+0x08)
-#define VPW_VPW(x) ( (x) & 0x3ff )
-
-#define LCDC_CPOS __REG(IMX_LCDC_BASE+0x0C)
-#define CPOS_CC1 (1<<31)
-#define CPOS_CC0 (1<<30)
-#define CPOS_OP (1<<28)
-#define CPOS_CXP(x) (((x) & 3ff) << 16)
-#define CPOS_CYP(y) ((y) & 0x1ff)
-
-#define LCDC_LCWHB __REG(IMX_LCDC_BASE+0x10)
-#define LCWHB_BK_EN (1<<31)
-#define LCWHB_CW(w) (((w) & 0x1f) << 24)
-#define LCWHB_CH(h) (((h) & 0x1f) << 16)
-#define LCWHB_BD(x) ((x) & 0xff)
-
-#define LCDC_LCHCC __REG(IMX_LCDC_BASE+0x14)
-#define LCHCC_CUR_COL_R(r) (((r) & 0x1f) << 11)
-#define LCHCC_CUR_COL_G(g) (((g) & 0x3f) << 5)
-#define LCHCC_CUR_COL_B(b) ((b) & 0x1f)
-
-#define LCDC_PCR __REG(IMX_LCDC_BASE+0x18)
-#define PCR_TFT (1<<31)
-#define PCR_COLOR (1<<30)
-#define PCR_PBSIZ_1 (0<<28)
-#define PCR_PBSIZ_2 (1<<28)
-#define PCR_PBSIZ_4 (2<<28)
-#define PCR_PBSIZ_8 (3<<28)
-#define PCR_BPIX_1 (0<<25)
-#define PCR_BPIX_2 (1<<25)
-#define PCR_BPIX_4 (2<<25)
-#define PCR_BPIX_8 (3<<25)
-#define PCR_BPIX_12 (4<<25)
-#define PCR_BPIX_16 (4<<25)
-#define PCR_PIXPOL (1<<24)
-#define PCR_FLMPOL (1<<23)
-#define PCR_LPPOL (1<<22)
-#define PCR_CLKPOL (1<<21)
-#define PCR_OEPOL (1<<20)
-#define PCR_SCLKIDLE (1<<19)
-#define PCR_END_SEL (1<<18)
-#define PCR_END_BYTE_SWAP (1<<17)
-#define PCR_REV_VS (1<<16)
-#define PCR_ACD_SEL (1<<15)
-#define PCR_ACD(x) (((x) & 0x7f) << 8)
-#define PCR_SCLK_SEL (1<<7)
-#define PCR_SHARP (1<<6)
-#define PCR_PCD(x) ((x) & 0x3f)
-
-#define LCDC_HCR __REG(IMX_LCDC_BASE+0x1C)
-#define HCR_H_WIDTH(x) (((x) & 0x3f) << 26)
-#define HCR_H_WAIT_1(x) (((x) & 0xff) << 8)
-#define HCR_H_WAIT_2(x) ((x) & 0xff)
-
-#define LCDC_VCR __REG(IMX_LCDC_BASE+0x20)
-#define VCR_V_WIDTH(x) (((x) & 0x3f) << 26)
-#define VCR_V_WAIT_1(x) (((x) & 0xff) << 8)
-#define VCR_V_WAIT_2(x) ((x) & 0xff)
-
-#define LCDC_POS __REG(IMX_LCDC_BASE+0x24)
-#define POS_POS(x) ((x) & 1f)
-
-#define LCDC_LSCR1 __REG(IMX_LCDC_BASE+0x28)
-#define LSCR1_PS_RISE_DELAY(x) (((x) & 0x7f) << 26)
-#define LSCR1_CLS_RISE_DELAY(x) (((x) & 0x3f) << 16)
-#define LSCR1_REV_TOGGLE_DELAY(x) (((x) & 0xf) << 8)
-#define LSCR1_GRAY2(x) (((x) & 0xf) << 4)
-#define LSCR1_GRAY1(x) (((x) & 0xf))
-
-#define LCDC_PWMR __REG(IMX_LCDC_BASE+0x2C)
-#define PWMR_CLS(x) (((x) & 0x1ff) << 16)
-#define PWMR_LDMSK (1<<15)
-#define PWMR_SCR1 (1<<10)
-#define PWMR_SCR0 (1<<9)
-#define PWMR_CC_EN (1<<8)
-#define PWMR_PW(x) ((x) & 0xff)
-
-#define LCDC_DMACR __REG(IMX_LCDC_BASE+0x30)
-#define DMACR_BURST (1<<31)
-#define DMACR_HM(x) (((x) & 0xf) << 16)
-#define DMACR_TM(x) ((x) &0xf)
-
-#define LCDC_RMCR __REG(IMX_LCDC_BASE+0x34)
-#define RMCR_LCDC_EN (1<<1)
-#define RMCR_SELF_REF (1<<0)
-
-#define LCDC_LCDICR __REG(IMX_LCDC_BASE+0x38)
-#define LCDICR_INT_SYN (1<<2)
-#define LCDICR_INT_CON (1)
-
-#define LCDC_LCDISR __REG(IMX_LCDC_BASE+0x40)
-#define LCDISR_UDR_ERR (1<<3)
-#define LCDISR_ERR_RES (1<<2)
-#define LCDISR_EOF (1<<1)
-#define LCDISR_BOF (1<<0)
-
#endif // _IMX_REGS_H
diff --git a/arch/arm/mach-w90x900/mach-w90p910evb.c b/arch/arm/mach-w90x900/mach-w90p910evb.c
index 9307a24..9ebc93f 100644
--- a/arch/arm/mach-w90x900/mach-w90p910evb.c
+++ b/arch/arm/mach-w90x900/mach-w90p910evb.c
@@ -29,6 +29,7 @@
#include <asm/mach-types.h>
#include <mach/regs-serial.h>
+#include <mach/map.h>
#include "cpu.h"
diff --git a/arch/arm/mach-w90x900/time.c b/arch/arm/mach-w90x900/time.c
index 3a69e38..bcc838f 100644
--- a/arch/arm/mach-w90x900/time.c
+++ b/arch/arm/mach-w90x900/time.c
@@ -28,7 +28,6 @@
#include <asm/mach/irq.h>
#include <asm/mach/time.h>
-#include <mach/system.h>
#include <mach/map.h>
#include <mach/regs-timer.h>
diff --git a/arch/arm/mm/proc-syms.c b/arch/arm/mm/proc-syms.c
index 4ad3bf2..195e48e 100644
--- a/arch/arm/mm/proc-syms.c
+++ b/arch/arm/mm/proc-syms.c
@@ -27,6 +27,7 @@ EXPORT_SYMBOL(__cpuc_flush_kern_all);
EXPORT_SYMBOL(__cpuc_flush_user_all);
EXPORT_SYMBOL(__cpuc_flush_user_range);
EXPORT_SYMBOL(__cpuc_coherent_kern_range);
+EXPORT_SYMBOL(dmac_inv_range); /* because of flush_ioremap_region() */
#else
EXPORT_SYMBOL(cpu_cache);
#endif
diff --git a/arch/arm/oprofile/op_model_mpcore.c b/arch/arm/oprofile/op_model_mpcore.c
index 6d6bd58..853d42b 100644
--- a/arch/arm/oprofile/op_model_mpcore.c
+++ b/arch/arm/oprofile/op_model_mpcore.c
@@ -263,7 +263,7 @@ static void em_route_irq(int irq, unsigned int cpu)
const struct cpumask *mask = cpumask_of(cpu);
spin_lock_irq(&desc->lock);
- desc->affinity = *mask;
+ cpumask_copy(desc->affinity, mask);
desc->chip->set_affinity(irq, mask);
spin_unlock_irq(&desc->lock);
}
diff --git a/arch/blackfin/kernel/irqchip.c b/arch/blackfin/kernel/irqchip.c
index ab8209c..5780d6d 100644
--- a/arch/blackfin/kernel/irqchip.c
+++ b/arch/blackfin/kernel/irqchip.c
@@ -69,6 +69,11 @@ static struct irq_desc bad_irq_desc = {
#endif
};
+#ifdef CONFIG_CPUMASK_OFFSTACK
+/* We are not allocating a variable-sized bad_irq_desc.affinity */
+#error "Blackfin architecture does not support CONFIG_CPUMASK_OFFSTACK."
+#endif
+
int show_interrupts(struct seq_file *p, void *v)
{
int i = *(loff_t *) v, j;
diff --git a/arch/ia64/kernel/iosapic.c b/arch/ia64/kernel/iosapic.c
index 5cfd3d9..006ad36 100644
--- a/arch/ia64/kernel/iosapic.c
+++ b/arch/ia64/kernel/iosapic.c
@@ -880,7 +880,7 @@ iosapic_unregister_intr (unsigned int gsi)
if (iosapic_intr_info[irq].count == 0) {
#ifdef CONFIG_SMP
/* Clear affinity */
- cpus_setall(idesc->affinity);
+ cpumask_setall(idesc->affinity);
#endif
/* Clear the interrupt information */
iosapic_intr_info[irq].dest = 0;
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
index a58f64c..226233a 100644
--- a/arch/ia64/kernel/irq.c
+++ b/arch/ia64/kernel/irq.c
@@ -103,7 +103,7 @@ static char irq_redir [NR_IRQS]; // = { [0 ... NR_IRQS-1] = 1 };
void set_irq_affinity_info (unsigned int irq, int hwid, int redir)
{
if (irq < NR_IRQS) {
- cpumask_copy(&irq_desc[irq].affinity,
+ cpumask_copy(irq_desc[irq].affinity,
cpumask_of(cpu_logical_id(hwid)));
irq_redir[irq] = (char) (redir & 0xff);
}
@@ -148,7 +148,7 @@ static void migrate_irqs(void)
if (desc->status == IRQ_PER_CPU)
continue;
- if (cpumask_any_and(&irq_desc[irq].affinity, cpu_online_mask)
+ if (cpumask_any_and(irq_desc[irq].affinity, cpu_online_mask)
>= nr_cpu_ids) {
/*
* Save it for phase 2 processing
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index 28d3d48..927ad02 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -493,11 +493,13 @@ ia64_handle_irq (ia64_vector vector, struct pt_regs *regs)
saved_tpr = ia64_getreg(_IA64_REG_CR_TPR);
ia64_srlz_d();
while (vector != IA64_SPURIOUS_INT_VECTOR) {
+ struct irq_desc *desc = irq_to_desc(vector);
+
if (unlikely(IS_LOCAL_TLB_FLUSH(vector))) {
smp_local_flush_tlb();
- kstat_this_cpu.irqs[vector]++;
+ kstat_incr_irqs_this_cpu(vector, desc);
} else if (unlikely(IS_RESCHEDULE(vector)))
- kstat_this_cpu.irqs[vector]++;
+ kstat_incr_irqs_this_cpu(vector, desc);
else {
int irq = local_vector_to_irq(vector);
@@ -551,11 +553,13 @@ void ia64_process_pending_intr(void)
* Perform normal interrupt style processing
*/
while (vector != IA64_SPURIOUS_INT_VECTOR) {
+ struct irq_desc *desc = irq_to_desc(vector);
+
if (unlikely(IS_LOCAL_TLB_FLUSH(vector))) {
smp_local_flush_tlb();
- kstat_this_cpu.irqs[vector]++;
+ kstat_incr_irqs_this_cpu(vector, desc);
} else if (unlikely(IS_RESCHEDULE(vector)))
- kstat_this_cpu.irqs[vector]++;
+ kstat_incr_irqs_this_cpu(vector, desc);
else {
struct pt_regs *old_regs = set_irq_regs(NULL);
int irq = local_vector_to_irq(vector);
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index 8903393..dcb6b7c 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -75,7 +75,7 @@ static void ia64_set_msi_irq_affinity(unsigned int irq,
msg.data = data;
write_msi_msg(irq, &msg);
- irq_desc[irq].affinity = cpumask_of_cpu(cpu);
+ cpumask_copy(irq_desc[irq].affinity, cpumask_of(cpu));
}
#endif /* CONFIG_SMP */
@@ -187,7 +187,7 @@ static void dmar_msi_set_affinity(unsigned int irq, const struct cpumask *mask)
msg.address_lo |= MSI_ADDR_DESTID_CPU(cpu_physical_id(cpu));
dmar_msi_write(irq, &msg);
- irq_desc[irq].affinity = *mask;
+ cpumask_copy(irq_desc[irq].affinity, mask);
}
#endif /* CONFIG_SMP */
diff --git a/arch/ia64/kernel/vmlinux.lds.S b/arch/ia64/kernel/vmlinux.lds.S
index 10a7d47e..f45e4e5 100644
--- a/arch/ia64/kernel/vmlinux.lds.S
+++ b/arch/ia64/kernel/vmlinux.lds.S
@@ -219,6 +219,7 @@ SECTIONS
.data.percpu PERCPU_ADDR : AT(__phys_per_cpu_start - LOAD_OFFSET)
{
__per_cpu_start = .;
+ *(.data.percpu.page_aligned)
*(.data.percpu)
*(.data.percpu.shared_aligned)
__per_cpu_end = .;
diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c
index ca553b0..81e4289 100644
--- a/arch/ia64/sn/kernel/msi_sn.c
+++ b/arch/ia64/sn/kernel/msi_sn.c
@@ -205,7 +205,7 @@ static void sn_set_msi_irq_affinity(unsigned int irq,
msg.address_lo = (u32)(bus_addr & 0x00000000ffffffff);
write_msi_msg(irq, &msg);
- irq_desc[irq].affinity = *cpu_mask;
+ cpumask_copy(irq_desc[irq].affinity, cpu_mask);
}
#endif /* CONFIG_SMP */
diff --git a/arch/m68k/amiga/amiints.c b/arch/m68k/amiga/amiints.c
index 907a553..c5b5212 100644
--- a/arch/m68k/amiga/amiints.c
+++ b/arch/m68k/amiga/amiints.c
@@ -72,10 +72,14 @@ static struct irq_controller amiga_irq_controller = {
void __init amiga_init_IRQ(void)
{
- request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL);
- request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL);
- request_irq(IRQ_AUTO_4, ami_int4, 0, "int4", NULL);
- request_irq(IRQ_AUTO_5, ami_int5, 0, "int5", NULL);
+ if (request_irq(IRQ_AUTO_1, ami_int1, 0, "int1", NULL))
+ pr_err("Couldn't register int%d\n", 1);
+ if (request_irq(IRQ_AUTO_3, ami_int3, 0, "int3", NULL))
+ pr_err("Couldn't register int%d\n", 3);
+ if (request_irq(IRQ_AUTO_4, ami_int4, 0, "int4", NULL))
+ pr_err("Couldn't register int%d\n", 4);
+ if (request_irq(IRQ_AUTO_5, ami_int5, 0, "int5", NULL))
+ pr_err("Couldn't register int%d\n", 5);
m68k_setup_irq_controller(&amiga_irq_controller, IRQ_USER, AMI_STD_IRQS);
diff --git a/arch/m68k/amiga/cia.c b/arch/m68k/amiga/cia.c
index 343fab4..ecd0f7c 100644
--- a/arch/m68k/amiga/cia.c
+++ b/arch/m68k/amiga/cia.c
@@ -176,5 +176,7 @@ void __init cia_init_IRQ(struct ciabase *base)
/* override auto int and install CIA handler */
m68k_setup_irq_controller(&auto_irq_controller, base->handler_irq, 1);
m68k_irq_startup(base->handler_irq);
- request_irq(base->handler_irq, cia_handler, IRQF_SHARED, base->name, base);
+ if (request_irq(base->handler_irq, cia_handler, IRQF_SHARED,
+ base->name, base))
+ pr_err("Couldn't register %s interrupt\n", base->name);
}
diff --git a/arch/m68k/amiga/config.c b/arch/m68k/amiga/config.c
index ab9862c..6e56275 100644
--- a/arch/m68k/amiga/config.c
+++ b/arch/m68k/amiga/config.c
@@ -493,7 +493,8 @@ static void __init amiga_sched_init(irq_handler_t timer_routine)
* Please don't change this to use ciaa, as it interferes with the
* SCSI code. We'll have to take a look at this later
*/
- request_irq(IRQ_AMIGA_CIAB_TA, timer_routine, 0, "timer", NULL);
+ if (request_irq(IRQ_AMIGA_CIAB_TA, timer_routine, 0, "timer", NULL))
+ pr_err("Couldn't register timer interrupt\n");
/* start timer */
ciab.cra |= 0x11;
}
diff --git a/arch/m68k/apollo/config.c b/arch/m68k/apollo/config.c
index 78df98f..8d3eafa 100644
--- a/arch/m68k/apollo/config.c
+++ b/arch/m68k/apollo/config.c
@@ -31,10 +31,6 @@ extern unsigned long dn_gettimeoffset(void);
extern int dn_dummy_hwclk(int, struct rtc_time *);
extern int dn_dummy_set_clock_mmss(unsigned long);
extern void dn_dummy_reset(void);
-extern void dn_dummy_waitbut(void);
-extern struct fb_info *dn_fb_init(long *);
-extern void dn_dummy_debug_init(void);
-extern irqreturn_t dn_process_int(int irq, struct pt_regs *fp);
#ifdef CONFIG_HEARTBEAT
static void dn_heartbeat(int on);
#endif
@@ -204,7 +200,8 @@ void dn_sched_init(irq_handler_t timer_routine)
printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3));
#endif
- request_irq(IRQ_APOLLO, dn_timer_int, 0, "time", timer_routine);
+ if (request_irq(IRQ_APOLLO, dn_timer_int, 0, "time", timer_routine))
+ pr_err("Couldn't register timer interrupt\n");
}
unsigned long dn_gettimeoffset(void) {
diff --git a/arch/m68k/atari/atakeyb.c b/arch/m68k/atari/atakeyb.c
index c038b7c..a5f33c0 100644
--- a/arch/m68k/atari/atakeyb.c
+++ b/arch/m68k/atari/atakeyb.c
@@ -33,7 +33,6 @@
#include <asm/atari_joystick.h>
#include <asm/irq.h>
-extern unsigned int keymap_count;
/* Hook for MIDI serial driver */
void (*atari_MIDI_interrupt_hook) (void);
@@ -567,14 +566,19 @@ static int atari_keyb_done = 0;
int atari_keyb_init(void)
{
+ int error;
+
if (atari_keyb_done)
return 0;
kb_state.state = KEYBOARD;
kb_state.len = 0;
- request_irq(IRQ_MFP_ACIA, atari_keyboard_interrupt, IRQ_TYPE_SLOW,
- "keyboard/mouse/MIDI", atari_keyboard_interrupt);
+ error = request_irq(IRQ_MFP_ACIA, atari_keyboard_interrupt,
+ IRQ_TYPE_SLOW, "keyboard/mouse/MIDI",
+ atari_keyboard_interrupt);
+ if (error)
+ return error;
atari_turnoff_irq(IRQ_MFP_ACIA);
do {
diff --git a/arch/m68k/atari/stdma.c b/arch/m68k/atari/stdma.c
index d1bd029..604329f 100644
--- a/arch/m68k/atari/stdma.c
+++ b/arch/m68k/atari/stdma.c
@@ -179,8 +179,9 @@ EXPORT_SYMBOL(stdma_islocked);
void __init stdma_init(void)
{
stdma_isr = NULL;
- request_irq(IRQ_MFP_FDC, stdma_int, IRQ_TYPE_SLOW | IRQF_SHARED,
- "ST-DMA: floppy/ACSI/IDE/Falcon-SCSI", stdma_int);
+ if (request_irq(IRQ_MFP_FDC, stdma_int, IRQ_TYPE_SLOW | IRQF_SHARED,
+ "ST-DMA: floppy/ACSI/IDE/Falcon-SCSI", stdma_int))
+ pr_err("Couldn't register ST-DMA interrupt\n");
}
diff --git a/arch/m68k/atari/time.c b/arch/m68k/atari/time.c
index 1edde27..d076ff8 100644
--- a/arch/m68k/atari/time.c
+++ b/arch/m68k/atari/time.c
@@ -31,8 +31,9 @@ atari_sched_init(irq_handler_t timer_routine)
/* start timer C, div = 1:100 */
mfp.tim_ct_cd = (mfp.tim_ct_cd & 15) | 0x60;
/* install interrupt service routine for MFP Timer C */
- request_irq(IRQ_MFP_TIMC, timer_routine, IRQ_TYPE_SLOW,
- "timer", timer_routine);
+ if (request_irq(IRQ_MFP_TIMC, timer_routine, IRQ_TYPE_SLOW,
+ "timer", timer_routine))
+ pr_err("Couldn't register timer interrupt\n");
}
/* ++andreas: gettimeoffset fixed to check for pending interrupt */
diff --git a/arch/m68k/bvme6000/config.c b/arch/m68k/bvme6000/config.c
index c072595..9fe6fef 100644
--- a/arch/m68k/bvme6000/config.c
+++ b/arch/m68k/bvme6000/config.c
@@ -43,7 +43,6 @@ extern unsigned long bvme6000_gettimeoffset (void);
extern int bvme6000_hwclk (int, struct rtc_time *);
extern int bvme6000_set_clock_mmss (unsigned long);
extern void bvme6000_reset (void);
-extern void bvme6000_waitbut(void);
void bvme6000_set_vectors (void);
/* Save tick handler routine pointer, will point to do_timer() in
diff --git a/arch/m68k/hp300/time.c b/arch/m68k/hp300/time.c
index dd7c8a2..f6312c7 100644
--- a/arch/m68k/hp300/time.c
+++ b/arch/m68k/hp300/time.c
@@ -70,7 +70,8 @@ void __init hp300_sched_init(irq_handler_t vector)
asm volatile(" movpw %0,%1@(5)" : : "d" (INTVAL), "a" (CLOCKBASE));
- request_irq(IRQ_AUTO_6, hp300_tick, IRQ_FLG_STD, "timer tick", vector);
+ if (request_irq(IRQ_AUTO_6, hp300_tick, IRQ_FLG_STD, "timer tick", vector))
+ pr_err("Couldn't register timer interrupt\n");
out_8(CLOCKBASE + CLKCR2, 0x1); /* select CR1 */
out_8(CLOCKBASE + CLKCR1, 0x40); /* enable irq */
diff --git a/arch/m68k/kernel/.gitignore b/arch/m68k/kernel/.gitignore
new file mode 100644
index 0000000..c5f676c
--- /dev/null
+++ b/arch/m68k/kernel/.gitignore
@@ -0,0 +1 @@
+vmlinux.lds
diff --git a/arch/m68k/kernel/entry.S b/arch/m68k/kernel/entry.S
index f28404d..5b78082 100644
--- a/arch/m68k/kernel/entry.S
+++ b/arch/m68k/kernel/entry.S
@@ -424,7 +424,7 @@ resume:
.data
ALIGN
sys_call_table:
- .long sys_ni_syscall /* 0 - old "setup()" system call*/
+ .long sys_restart_syscall /* 0 - old "setup()" system call, used for restarting */
.long sys_exit
.long sys_fork
.long sys_read
diff --git a/arch/m68k/kernel/setup.c b/arch/m68k/kernel/setup.c
index 4d97bd2..303730a 100644
--- a/arch/m68k/kernel/setup.c
+++ b/arch/m68k/kernel/setup.c
@@ -26,6 +26,7 @@
#include <linux/initrd.h>
#include <asm/bootinfo.h>
+#include <asm/sections.h>
#include <asm/setup.h>
#include <asm/fpu.h>
#include <asm/irq.h>
@@ -62,7 +63,6 @@ EXPORT_SYMBOL(vme_brdtype);
int m68k_is040or060;
EXPORT_SYMBOL(m68k_is040or060);
-extern int end;
extern unsigned long availmem;
int m68k_num_memory;
@@ -215,11 +215,10 @@ static void __init m68k_parse_bootinfo(const struct bi_record *record)
void __init setup_arch(char **cmdline_p)
{
- extern int _etext, _edata, _end;
int i;
/* The bootinfo is located right after the kernel bss */
- m68k_parse_bootinfo((const struct bi_record *)&_end);
+ m68k_parse_bootinfo((const struct bi_record *)_end);
if (CPU_IS_040)
m68k_is040or060 = 4;
@@ -252,9 +251,9 @@ void __init setup_arch(char **cmdline_p)
}
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) &_end;
+ init_mm.end_code = (unsigned long)_etext;
+ init_mm.end_data = (unsigned long)_edata;
+ init_mm.brk = (unsigned long)_end;
*cmdline_p = m68k_command_line;
memcpy(boot_command_line, *cmdline_p, CL_SIZE);
diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c
index f9af893..de2d05d 100644
--- a/arch/m68k/kernel/signal.c
+++ b/arch/m68k/kernel/signal.c
@@ -326,6 +326,9 @@ restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *usc, void __u
struct sigcontext context;
int err;
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
/* get previous context */
if (copy_from_user(&context, usc, sizeof(context)))
goto badframe;
@@ -411,6 +414,9 @@ rt_restore_ucontext(struct pt_regs *regs, struct switch_stack *sw,
unsigned long usp;
int err;
+ /* Always make any pending restarted system calls return -EINTR */
+ current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
err = __get_user(temp, &uc->uc_mcontext.version);
if (temp != MCONTEXT_VERSION)
goto badframe;
@@ -937,6 +943,15 @@ handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
regs->d0 = -EINTR;
break;
+ case -ERESTART_RESTARTBLOCK:
+ if (!has_handler) {
+ regs->d0 = __NR_restart_syscall;
+ regs->pc -= 2;
+ break;
+ }
+ regs->d0 = -EINTR;
+ break;
+
case -ERESTARTSYS:
if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
regs->d0 = -EINTR;
diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds
index 8a4919e..d9368c0 100644
--- a/arch/m68k/kernel/vmlinux-sun3.lds
+++ b/arch/m68k/kernel/vmlinux-sun3.lds
@@ -33,6 +33,7 @@ SECTIONS
} :data
/* End of data goes *here* so that freeing init code works properly. */
_edata = .;
+ NOTES
/* will be freed after init */
. = ALIGN(PAGE_SIZE); /* Init code and data */
diff --git a/arch/m68k/mac/baboon.c b/arch/m68k/mac/baboon.c
index 245d16d..2a96beb 100644
--- a/arch/m68k/mac/baboon.c
+++ b/arch/m68k/mac/baboon.c
@@ -92,7 +92,8 @@ static irqreturn_t baboon_irq(int irq, void *dev_id)
void __init baboon_register_interrupts(void)
{
baboon_disabled = 0;
- request_irq(IRQ_NUBUS_C, baboon_irq, 0, "baboon", (void *)baboon);
+ if (request_irq(IRQ_NUBUS_C, baboon_irq, 0, "baboon", (void *)baboon))
+ pr_err("Couldn't register baboon interrupt\n");
}
/*
diff --git a/arch/m68k/mac/config.c b/arch/m68k/mac/config.c
index 8819b97..98b6bcf 100644
--- a/arch/m68k/mac/config.c
+++ b/arch/m68k/mac/config.c
@@ -47,13 +47,6 @@
struct mac_booter_data mac_bi_data;
-/* New m68k bootinfo stuff and videobase */
-
-extern int m68k_num_memory;
-extern struct mem_info m68k_memory[NUM_MEMINFO];
-
-extern struct mem_info m68k_ramdisk;
-
/* The phys. video addr. - might be bogus on some machines */
static unsigned long mac_orig_videoaddr;
@@ -61,7 +54,6 @@ static unsigned long mac_orig_videoaddr;
extern unsigned long mac_gettimeoffset(void);
extern int mac_hwclk(int, struct rtc_time *);
extern int mac_set_clock_mmss(unsigned long);
-extern int show_mac_interrupts(struct seq_file *, void *);
extern void iop_preinit(void);
extern void iop_init(void);
extern void via_init(void);
@@ -805,10 +797,6 @@ static void __init mac_identify(void)
mac_bi_data.boottime, mac_bi_data.gmtbias);
printk(KERN_DEBUG " Machine ID: %ld CPUid: 0x%lx memory size: 0x%lx \n",
mac_bi_data.id, mac_bi_data.cpuid, mac_bi_data.memsize);
-#if 0
- printk("Ramdisk: addr 0x%lx size 0x%lx\n",
- m68k_ramdisk.addr, m68k_ramdisk.size);
-#endif
iop_init();
via_init();
diff --git a/arch/m68k/mac/debug.c b/arch/m68k/mac/debug.c
index 65dd77a..bce074c 100644
--- a/arch/m68k/mac/debug.c
+++ b/arch/m68k/mac/debug.c
@@ -27,7 +27,6 @@
#include <asm/macints.h>
extern unsigned long mac_videobase;
-extern unsigned long mac_videodepth;
extern unsigned long mac_rowbytes;
extern void mac_serial_print(const char *);
diff --git a/arch/m68k/mac/iop.c b/arch/m68k/mac/iop.c
index 326fb99..1ad4e9d 100644
--- a/arch/m68k/mac/iop.c
+++ b/arch/m68k/mac/iop.c
@@ -305,14 +305,16 @@ void __init iop_register_interrupts(void)
{
if (iop_ism_present) {
if (oss_present) {
- request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq,
+ if (request_irq(OSS_IRQLEV_IOPISM, iop_ism_irq,
IRQ_FLG_LOCK, "ISM IOP",
- (void *) IOP_NUM_ISM);
+ (void *) IOP_NUM_ISM))
+ pr_err("Couldn't register ISM IOP interrupt\n");
oss_irq_enable(IRQ_MAC_ADB);
} else {
- request_irq(IRQ_VIA2_0, iop_ism_irq,
+ if (request_irq(IRQ_VIA2_0, iop_ism_irq,
IRQ_FLG_LOCK|IRQ_FLG_FAST, "ISM IOP",
- (void *) IOP_NUM_ISM);
+ (void *) IOP_NUM_ISM))
+ pr_err("Couldn't register ISM IOP interrupt\n");
}
if (!iop_alive(iop_base[IOP_NUM_ISM])) {
printk("IOP: oh my god, they killed the ISM IOP!\n");
diff --git a/arch/m68k/mac/macints.c b/arch/m68k/mac/macints.c
index 82e560c..2371107 100644
--- a/arch/m68k/mac/macints.c
+++ b/arch/m68k/mac/macints.c
@@ -134,6 +134,7 @@
#include <asm/errno.h>
#include <asm/macints.h>
#include <asm/irq_regs.h>
+#include <asm/mac_oss.h>
#define DEBUG_SPURIOUS
#define SHUTUP_SONIC
@@ -146,7 +147,6 @@ static int scc_mask;
* VIA/RBV hooks
*/
-extern void via_init(void);
extern void via_register_interrupts(void);
extern void via_irq_enable(int);
extern void via_irq_disable(int);
@@ -157,9 +157,6 @@ extern int via_irq_pending(int);
* OSS hooks
*/
-extern int oss_present;
-
-extern void oss_init(void);
extern void oss_register_interrupts(void);
extern void oss_irq_enable(int);
extern void oss_irq_disable(int);
@@ -170,9 +167,6 @@ extern int oss_irq_pending(int);
* PSC hooks
*/
-extern int psc_present;
-
-extern void psc_init(void);
extern void psc_register_interrupts(void);
extern void psc_irq_enable(int);
extern void psc_irq_disable(int);
@@ -191,12 +185,10 @@ extern void iop_register_interrupts(void);
extern int baboon_present;
-extern void baboon_init(void);
extern void baboon_register_interrupts(void);
extern void baboon_irq_enable(int);
extern void baboon_irq_disable(int);
extern void baboon_irq_clear(int);
-extern int baboon_irq_pending(int);
/*
* SCC interrupt routines
@@ -258,8 +250,9 @@ void __init mac_init_IRQ(void)
if (baboon_present)
baboon_register_interrupts();
iop_register_interrupts();
- request_irq(IRQ_AUTO_7, mac_nmi_handler, 0, "NMI",
- mac_nmi_handler);
+ if (request_irq(IRQ_AUTO_7, mac_nmi_handler, 0, "NMI",
+ mac_nmi_handler))
+ pr_err("Couldn't register NMI\n");
#ifdef DEBUG_MACINTS
printk("mac_init_IRQ(): Done!\n");
#endif
diff --git a/arch/m68k/mac/misc.c b/arch/m68k/mac/misc.c
index a44c708..5d81856 100644
--- a/arch/m68k/mac/misc.c
+++ b/arch/m68k/mac/misc.c
@@ -35,7 +35,6 @@
#define RTC_OFFSET 2082844800
-extern struct mac_booter_data mac_bi_data;
static void (*rom_reset)(void);
#ifdef CONFIG_ADB_CUDA
diff --git a/arch/m68k/mac/oss.c b/arch/m68k/mac/oss.c
index 8426501..f3d23d6 100644
--- a/arch/m68k/mac/oss.c
+++ b/arch/m68k/mac/oss.c
@@ -66,16 +66,21 @@ void __init oss_init(void)
void __init oss_register_interrupts(void)
{
- request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK,
- "scsi", (void *) oss);
- request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK,
- "scc", mac_scc_dispatch);
- request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK,
- "nubus", (void *) oss);
- request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK,
- "sound", (void *) oss);
- request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK,
- "via1", (void *) via1);
+ if (request_irq(OSS_IRQLEV_SCSI, oss_irq, IRQ_FLG_LOCK,
+ "scsi", (void *) oss))
+ pr_err("Couldn't register %s interrupt\n", "scsi");
+ if (request_irq(OSS_IRQLEV_IOPSCC, mac_scc_dispatch, IRQ_FLG_LOCK,
+ "scc", mac_scc_dispatch))
+ pr_err("Couldn't register %s interrupt\n", "scc");
+ if (request_irq(OSS_IRQLEV_NUBUS, oss_nubus_irq, IRQ_FLG_LOCK,
+ "nubus", (void *) oss))
+ pr_err("Couldn't register %s interrupt\n", "nubus");
+ if (request_irq(OSS_IRQLEV_SOUND, oss_irq, IRQ_FLG_LOCK,
+ "sound", (void *) oss))
+ pr_err("Couldn't register %s interrupt\n", "sound");
+ if (request_irq(OSS_IRQLEV_VIA1, via1_irq, IRQ_FLG_LOCK,
+ "via1", (void *) via1))
+ pr_err("Couldn't register %s interrupt\n", "via1");
}
/*
diff --git a/arch/m68k/mac/psc.c b/arch/m68k/mac/psc.c
index f84a4dd..ba6ccab 100644
--- a/arch/m68k/mac/psc.c
+++ b/arch/m68k/mac/psc.c
@@ -117,10 +117,14 @@ void __init psc_init(void)
void __init psc_register_interrupts(void)
{
- request_irq(IRQ_AUTO_3, psc_irq, 0, "psc3", (void *) 0x30);
- request_irq(IRQ_AUTO_4, psc_irq, 0, "psc4", (void *) 0x40);
- request_irq(IRQ_AUTO_5, psc_irq, 0, "psc5", (void *) 0x50);
- request_irq(IRQ_AUTO_6, psc_irq, 0, "psc6", (void *) 0x60);
+ if (request_irq(IRQ_AUTO_3, psc_irq, 0, "psc3", (void *) 0x30))
+ pr_err("Couldn't register psc%d interrupt\n", 3);
+ if (request_irq(IRQ_AUTO_4, psc_irq, 0, "psc4", (void *) 0x40))
+ pr_err("Couldn't register psc%d interrupt\n", 4);
+ if (request_irq(IRQ_AUTO_5, psc_irq, 0, "psc5", (void *) 0x50))
+ pr_err("Couldn't register psc%d interrupt\n", 5);
+ if (request_irq(IRQ_AUTO_6, psc_irq, 0, "psc6", (void *) 0x60))
+ pr_err("Couldn't register psc%d interrupt\n", 6);
}
/*
diff --git a/arch/m68k/mac/via.c b/arch/m68k/mac/via.c
index f01d418..7d97ba5 100644
--- a/arch/m68k/mac/via.c
+++ b/arch/m68k/mac/via.c
@@ -34,6 +34,7 @@
#include <asm/macints.h>
#include <asm/mac_via.h>
#include <asm/mac_psc.h>
+#include <asm/mac_oss.h>
volatile __u8 *via1, *via2;
int rbv_present;
@@ -84,7 +85,6 @@ void via_irq_disable(int irq);
void via_irq_clear(int irq);
extern irqreturn_t mac_scc_dispatch(int, void *);
-extern int oss_present;
/*
* Initialize the VIAs
@@ -283,7 +283,8 @@ void __init via_init_clock(irq_handler_t func)
via1[vT1CL] = MAC_CLOCK_LOW;
via1[vT1CH] = MAC_CLOCK_HIGH;
- request_irq(IRQ_MAC_TIMER_1, func, IRQ_FLG_LOCK, "timer", func);
+ if (request_irq(IRQ_MAC_TIMER_1, func, IRQ_FLG_LOCK, "timer", func))
+ pr_err("Couldn't register %s interrupt\n", "timer");
}
/*
@@ -293,25 +294,31 @@ void __init via_init_clock(irq_handler_t func)
void __init via_register_interrupts(void)
{
if (via_alt_mapping) {
- request_irq(IRQ_AUTO_1, via1_irq,
+ if (request_irq(IRQ_AUTO_1, via1_irq,
IRQ_FLG_LOCK|IRQ_FLG_FAST, "software",
- (void *) via1);
- request_irq(IRQ_AUTO_6, via1_irq,
+ (void *) via1))
+ pr_err("Couldn't register %s interrupt\n", "software");
+ if (request_irq(IRQ_AUTO_6, via1_irq,
IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1",
- (void *) via1);
+ (void *) via1))
+ pr_err("Couldn't register %s interrupt\n", "via1");
} else {
- request_irq(IRQ_AUTO_1, via1_irq,
+ if (request_irq(IRQ_AUTO_1, via1_irq,
IRQ_FLG_LOCK|IRQ_FLG_FAST, "via1",
- (void *) via1);
+ (void *) via1))
+ pr_err("Couldn't register %s interrupt\n", "via1");
}
- request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST,
- "via2", (void *) via2);
+ if (request_irq(IRQ_AUTO_2, via2_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST,
+ "via2", (void *) via2))
+ pr_err("Couldn't register %s interrupt\n", "via2");
if (!psc_present) {
- request_irq(IRQ_AUTO_4, mac_scc_dispatch, IRQ_FLG_LOCK,
- "scc", mac_scc_dispatch);
+ if (request_irq(IRQ_AUTO_4, mac_scc_dispatch, IRQ_FLG_LOCK,
+ "scc", mac_scc_dispatch))
+ pr_err("Couldn't register %s interrupt\n", "scc");
}
- request_irq(IRQ_MAC_NUBUS, via_nubus_irq, IRQ_FLG_LOCK|IRQ_FLG_FAST,
- "nubus", (void *) via2);
+ if (request_irq(IRQ_MAC_NUBUS, via_nubus_irq,
+ IRQ_FLG_LOCK|IRQ_FLG_FAST, "nubus", (void *) via2))
+ pr_err("Couldn't register %s interrupt\n", "nubus");
}
/*
diff --git a/arch/m68k/math-emu/fp_log.c b/arch/m68k/math-emu/fp_log.c
index b1033ae..367ecee 100644
--- a/arch/m68k/math-emu/fp_log.c
+++ b/arch/m68k/math-emu/fp_log.c
@@ -24,7 +24,6 @@ static const struct fp_ext fp_one =
extern struct fp_ext *fp_fadd(struct fp_ext *dest, const struct fp_ext *src);
extern struct fp_ext *fp_fdiv(struct fp_ext *dest, const struct fp_ext *src);
-extern struct fp_ext *fp_fmul(struct fp_ext *dest, const struct fp_ext *src);
struct fp_ext *
fp_fsqrt(struct fp_ext *dest, struct fp_ext *src)
diff --git a/arch/m68k/mm/init.c b/arch/m68k/mm/init.c
index 81bb08c..0007b2a 100644
--- a/arch/m68k/mm/init.c
+++ b/arch/m68k/mm/init.c
@@ -28,6 +28,7 @@
#ifdef CONFIG_ATARI
#include <asm/atari_stram.h>
#endif
+#include <asm/sections.h>
#include <asm/tlb.h>
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
@@ -73,9 +74,6 @@ extern void init_pointer_table(unsigned long ptable);
/* References to section boundaries */
-extern char _text[], _etext[];
-extern char __init_begin[], __init_end[];
-
extern pmd_t *zero_pgtable;
void __init mem_init(void)
diff --git a/arch/m68k/mm/motorola.c b/arch/m68k/mm/motorola.c
index c5dbb9b..4665fc8 100644
--- a/arch/m68k/mm/motorola.c
+++ b/arch/m68k/mm/motorola.c
@@ -30,6 +30,7 @@
#ifdef CONFIG_ATARI
#include <asm/atari_stram.h>
#endif
+#include <asm/sections.h>
#undef DEBUG
@@ -301,14 +302,12 @@ void __init paging_init(void)
}
}
-extern char __init_begin, __init_end;
-
void free_initmem(void)
{
unsigned long addr;
- addr = (unsigned long)&__init_begin;
- for (; addr < (unsigned long)&__init_end; addr += PAGE_SIZE) {
+ addr = (unsigned long)__init_begin;
+ for (; addr < (unsigned long)__init_end; addr += PAGE_SIZE) {
virt_to_page(addr)->flags &= ~(1 << PG_reserved);
init_page_count(virt_to_page(addr));
free_page(addr);
diff --git a/arch/m68k/mvme147/config.c b/arch/m68k/mvme147/config.c
index 43cdf47..100baaa 100644
--- a/arch/m68k/mvme147/config.c
+++ b/arch/m68k/mvme147/config.c
@@ -42,7 +42,6 @@ extern unsigned long mvme147_gettimeoffset (void);
extern int mvme147_hwclk (int, struct rtc_time *);
extern int mvme147_set_clock_mmss (unsigned long);
extern void mvme147_reset (void);
-extern void mvme147_waitbut(void);
static int bcd2int (unsigned char b);
@@ -115,8 +114,9 @@ static irqreturn_t mvme147_timer_int (int irq, void *dev_id)
void mvme147_sched_init (irq_handler_t timer_routine)
{
tick_handler = timer_routine;
- request_irq (PCC_IRQ_TIMER1, mvme147_timer_int,
- IRQ_FLG_REPLACE, "timer 1", NULL);
+ if (request_irq(PCC_IRQ_TIMER1, mvme147_timer_int, IRQ_FLG_REPLACE,
+ "timer 1", NULL))
+ pr_err("Couldn't register timer interrupt\n");
/* Init the clock with a value */
/* our clock goes off every 6.25us */
diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c
index 1521826..11edf61 100644
--- a/arch/m68k/mvme16x/config.c
+++ b/arch/m68k/mvme16x/config.c
@@ -48,7 +48,6 @@ extern unsigned long mvme16x_gettimeoffset (void);
extern int mvme16x_hwclk (int, struct rtc_time *);
extern int mvme16x_set_clock_mmss (unsigned long);
extern void mvme16x_reset (void);
-extern void mvme16x_waitbut(void);
int bcd2int (unsigned char b);
diff --git a/arch/m68k/q40/config.c b/arch/m68k/q40/config.c
index 7110546..31ab3f0 100644
--- a/arch/m68k/q40/config.c
+++ b/arch/m68k/q40/config.c
@@ -36,7 +36,6 @@
#include <asm/machdep.h>
#include <asm/q40_master.h>
-extern irqreturn_t q40_process_int(int level, struct pt_regs *regs);
extern void q40_init_IRQ(void);
static void q40_get_model(char *model);
extern void q40_sched_init(irq_handler_t handler);
@@ -47,8 +46,6 @@ static unsigned int q40_get_ss(void);
static int q40_set_clock_mmss(unsigned long);
static int q40_get_rtc_pll(struct rtc_pll_info *pll);
static int q40_set_rtc_pll(struct rtc_pll_info *pll);
-extern void q40_waitbut(void);
-void q40_set_vectors(void);
extern void q40_mksound(unsigned int /*freq*/, unsigned int /*ticks*/);
diff --git a/arch/m68k/sun3/config.c b/arch/m68k/sun3/config.c
index 8dfaa20..2ca25bd 100644
--- a/arch/m68k/sun3/config.c
+++ b/arch/m68k/sun3/config.c
@@ -27,23 +27,21 @@
#include <asm/sun3mmu.h>
#include <asm/rtc.h>
#include <asm/machdep.h>
+#include <asm/idprom.h>
#include <asm/intersil.h>
#include <asm/irq.h>
+#include <asm/sections.h>
#include <asm/segment.h>
#include <asm/sun3ints.h>
-extern char _text, _end;
-
char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
extern unsigned long sun3_gettimeoffset(void);
static void sun3_sched_init(irq_handler_t handler);
extern void sun3_get_model (char* model);
-extern void idprom_init (void);
extern int sun3_hwclk(int set, struct rtc_time *t);
volatile char* clock_va;
-extern volatile unsigned char* sun3_intreg;
extern unsigned long availmem;
unsigned long num_pages;
@@ -149,7 +147,7 @@ void __init config_sun3(void)
mach_halt = sun3_halt;
mach_get_hardware_list = sun3_get_hardware_list;
- memory_start = ((((int)&_end) + 0x2000) & ~0x1fff);
+ memory_start = ((((unsigned long)_end) + 0x2000) & ~0x1fff);
// PROM seems to want the last couple of physical pages. --m
memory_end = *(romvec->pv_sun3mem) + PAGE_OFFSET - 2*PAGE_SIZE;
diff --git a/arch/m68k/sun3/mmu_emu.c b/arch/m68k/sun3/mmu_emu.c
index 60f9d45..3cd1939 100644
--- a/arch/m68k/sun3/mmu_emu.c
+++ b/arch/m68k/sun3/mmu_emu.c
@@ -27,7 +27,6 @@
#include <asm/mmu_context.h>
#include <asm/dvma.h>
-extern void prom_reboot (char *) __attribute__ ((__noreturn__));
#undef DEBUG_MMU_EMU
#define DEBUG_PROM_MAPS
diff --git a/arch/m68k/sun3/sun3ints.c b/arch/m68k/sun3/sun3ints.c
index 7364cd6..ad90393 100644
--- a/arch/m68k/sun3/sun3ints.c
+++ b/arch/m68k/sun3/sun3ints.c
@@ -105,7 +105,10 @@ void __init sun3_init_IRQ(void)
m68k_setup_irq_controller(&sun3_irq_controller, IRQ_AUTO_1, 7);
m68k_setup_user_interrupt(VEC_USER, 128, NULL);
- request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL);
- request_irq(IRQ_AUTO_7, sun3_int7, 0, "int7", NULL);
- request_irq(IRQ_USER+127, sun3_vec255, 0, "vec255", NULL);
+ if (request_irq(IRQ_AUTO_5, sun3_int5, 0, "int5", NULL))
+ pr_err("Couldn't register %s interrupt\n", "int5");
+ if (request_irq(IRQ_AUTO_7, sun3_int7, 0, "int7", NULL))
+ pr_err("Couldn't register %s interrupt\n", "int7");
+ if (request_irq(IRQ_USER+127, sun3_vec255, 0, "vec255", NULL))
+ pr_err("Couldn't register %s interrupt\n", "vec255");
}
diff --git a/arch/m68k/sun3x/config.c b/arch/m68k/sun3x/config.c
index 2b1ca2d..fc599fa 100644
--- a/arch/m68k/sun3x/config.c
+++ b/arch/m68k/sun3x/config.c
@@ -23,7 +23,6 @@
#include "time.h"
volatile char *clock_va;
-extern volatile unsigned char *sun3_intreg;
extern void sun3_get_model(char *model);
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index a5255e7..52c80c2 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -595,6 +595,44 @@ config WR_PPMC
This enables support for the Wind River MIPS32 4KC PPMC evaluation
board, which is based on GT64120 bridge chip.
+config CAVIUM_OCTEON_SIMULATOR
+ bool "Support for the Cavium Networks Octeon Simulator"
+ select CEVT_R4K
+ select 64BIT_PHYS_ADDR
+ select DMA_COHERENT
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select CPU_CAVIUM_OCTEON
+ help
+ The Octeon simulator is software performance model of the Cavium
+ Octeon Processor. It supports simulating Octeon processors on x86
+ hardware.
+
+config CAVIUM_OCTEON_REFERENCE_BOARD
+ bool "Support for the Cavium Networks Octeon reference board"
+ select CEVT_R4K
+ select 64BIT_PHYS_ADDR
+ select DMA_COHERENT
+ select SYS_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_BIG_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_HAS_EARLY_PRINTK
+ select CPU_CAVIUM_OCTEON
+ select SWAP_IO_SPACE
+ help
+ This option supports all of the Octeon reference boards from Cavium
+ Networks. It builds a kernel that dynamically determines the Octeon
+ CPU type and supports all known board reference implementations.
+ Some of the supported boards are:
+ EBT3000
+ EBH3000
+ EBH3100
+ Thunder
+ Kodama
+ Hikari
+ Say Y here for most Octeon reference boards.
+
endchoice
source "arch/mips/alchemy/Kconfig"
@@ -607,6 +645,7 @@ source "arch/mips/sgi-ip27/Kconfig"
source "arch/mips/sibyte/Kconfig"
source "arch/mips/txx9/Kconfig"
source "arch/mips/vr41xx/Kconfig"
+source "arch/mips/cavium-octeon/Kconfig"
endmenu
@@ -682,7 +721,11 @@ config CEVT_DS1287
config CEVT_GT641XX
bool
+config CEVT_R4K_LIB
+ bool
+
config CEVT_R4K
+ select CEVT_R4K_LIB
bool
config CEVT_SB1250
@@ -697,7 +740,11 @@ config CSRC_BCM1480
config CSRC_IOASIC
bool
+config CSRC_R4K_LIB
+ bool
+
config CSRC_R4K
+ select CSRC_R4K_LIB
bool
config CSRC_SB1250
@@ -835,6 +882,9 @@ config IRQ_GT641XX
config IRQ_GIC
bool
+config IRQ_CPU_OCTEON
+ bool
+
config MIPS_BOARDS_GEN
bool
@@ -924,7 +974,7 @@ config BOOT_ELF32
config MIPS_L1_CACHE_SHIFT
int
default "4" if MACH_DECSTATION || MIKROTIK_RB532
- default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM
+ default "7" if SGI_IP22 || SGI_IP27 || SGI_IP28 || SNI_RM || CPU_CAVIUM_OCTEON
default "4" if PMC_MSP4200_EVAL
default "5"
@@ -1185,6 +1235,23 @@ config CPU_SB1
select CPU_SUPPORTS_HIGHMEM
select WEAK_ORDERING
+config CPU_CAVIUM_OCTEON
+ bool "Cavium Octeon processor"
+ select IRQ_CPU
+ select IRQ_CPU_OCTEON
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_64BIT_KERNEL
+ select SYS_SUPPORTS_SMP
+ select NR_CPUS_DEFAULT_16
+ select WEAK_ORDERING
+ select WEAK_REORDERING_BEYOND_LLSC
+ select CPU_SUPPORTS_HIGHMEM
+ help
+ The Cavium Octeon processor is a highly integrated chip containing
+ many ethernet hardware widgets for networking tasks. The processor
+ can have up to 16 Mips64v2 cores and 8 integrated gigabit ethernets.
+ Full details can be found at http://www.caviumnetworks.com.
+
endchoice
config SYS_HAS_CPU_LOONGSON2
@@ -1285,7 +1352,7 @@ config CPU_MIPSR1
config CPU_MIPSR2
bool
- default y if CPU_MIPS32_R2 || CPU_MIPS64_R2
+ default y if CPU_MIPS32_R2 || CPU_MIPS64_R2 || CPU_CAVIUM_OCTEON
config SYS_SUPPORTS_32BIT_KERNEL
bool
diff --git a/arch/mips/Makefile b/arch/mips/Makefile
index 28c55f6..21b00e9 100644
--- a/arch/mips/Makefile
+++ b/arch/mips/Makefile
@@ -144,6 +144,10 @@ cflags-$(CONFIG_CPU_SB1) += $(call cc-option,-march=sb1,-march=r5000) \
cflags-$(CONFIG_CPU_R8000) += -march=r8000 -Wa,--trap
cflags-$(CONFIG_CPU_R10000) += $(call cc-option,-march=r10000,-march=r8000) \
-Wa,--trap
+cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += $(call cc-option,-march=octeon) -Wa,--trap
+ifeq (,$(findstring march=octeon, $(cflags-$(CONFIG_CPU_CAVIUM_OCTEON))))
+cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -Wa,-march=octeon
+endif
cflags-$(CONFIG_CPU_R4000_WORKAROUNDS) += $(call cc-option,-mfix-r4000,)
cflags-$(CONFIG_CPU_R4400_WORKAROUNDS) += $(call cc-option,-mfix-r4400,)
@@ -184,84 +188,84 @@ cflags-$(CONFIG_SOC_AU1X00) += -I$(srctree)/arch/mips/include/asm/mach-au1x00
#
# AMD Alchemy Pb1000 eval board
#
-libs-$(CONFIG_MIPS_PB1000) += arch/mips/alchemy/pb1000/
+core-$(CONFIG_MIPS_PB1000) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_PB1000) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
load-$(CONFIG_MIPS_PB1000) += 0xffffffff80100000
#
# AMD Alchemy Pb1100 eval board
#
-libs-$(CONFIG_MIPS_PB1100) += arch/mips/alchemy/pb1100/
+core-$(CONFIG_MIPS_PB1100) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_PB1100) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
load-$(CONFIG_MIPS_PB1100) += 0xffffffff80100000
#
# AMD Alchemy Pb1500 eval board
#
-libs-$(CONFIG_MIPS_PB1500) += arch/mips/alchemy/pb1500/
+core-$(CONFIG_MIPS_PB1500) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_PB1500) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
load-$(CONFIG_MIPS_PB1500) += 0xffffffff80100000
#
# AMD Alchemy Pb1550 eval board
#
-libs-$(CONFIG_MIPS_PB1550) += arch/mips/alchemy/pb1550/
+core-$(CONFIG_MIPS_PB1550) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_PB1550) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
load-$(CONFIG_MIPS_PB1550) += 0xffffffff80100000
#
# AMD Alchemy Pb1200 eval board
#
-libs-$(CONFIG_MIPS_PB1200) += arch/mips/alchemy/pb1200/
+core-$(CONFIG_MIPS_PB1200) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_PB1200) += -I$(srctree)/arch/mips/include/asm/mach-pb1x00
load-$(CONFIG_MIPS_PB1200) += 0xffffffff80100000
#
# AMD Alchemy Db1000 eval board
#
-libs-$(CONFIG_MIPS_DB1000) += arch/mips/alchemy/db1x00/
+core-$(CONFIG_MIPS_DB1000) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_DB1000) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1000) += 0xffffffff80100000
#
# AMD Alchemy Db1100 eval board
#
-libs-$(CONFIG_MIPS_DB1100) += arch/mips/alchemy/db1x00/
+core-$(CONFIG_MIPS_DB1100) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_DB1100) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1100) += 0xffffffff80100000
#
# AMD Alchemy Db1500 eval board
#
-libs-$(CONFIG_MIPS_DB1500) += arch/mips/alchemy/db1x00/
+core-$(CONFIG_MIPS_DB1500) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_DB1500) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1500) += 0xffffffff80100000
#
# AMD Alchemy Db1550 eval board
#
-libs-$(CONFIG_MIPS_DB1550) += arch/mips/alchemy/db1x00/
+core-$(CONFIG_MIPS_DB1550) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_DB1550) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1550) += 0xffffffff80100000
#
# AMD Alchemy Db1200 eval board
#
-libs-$(CONFIG_MIPS_DB1200) += arch/mips/alchemy/pb1200/
+core-$(CONFIG_MIPS_DB1200) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_DB1200) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_DB1200) += 0xffffffff80100000
#
# AMD Alchemy Bosporus eval board
#
-libs-$(CONFIG_MIPS_BOSPORUS) += arch/mips/alchemy/db1x00/
+core-$(CONFIG_MIPS_BOSPORUS) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_BOSPORUS) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_BOSPORUS) += 0xffffffff80100000
#
# AMD Alchemy Mirage eval board
#
-libs-$(CONFIG_MIPS_MIRAGE) += arch/mips/alchemy/db1x00/
+core-$(CONFIG_MIPS_MIRAGE) += arch/mips/alchemy/devboards/
cflags-$(CONFIG_MIPS_MIRAGE) += -I$(srctree)/arch/mips/include/asm/mach-db1x00
load-$(CONFIG_MIPS_MIRAGE) += 0xffffffff80100000
@@ -586,6 +590,18 @@ core-$(CONFIG_TOSHIBA_RBTX4927) += arch/mips/txx9/rbtx4927/
core-$(CONFIG_TOSHIBA_RBTX4938) += arch/mips/txx9/rbtx4938/
core-$(CONFIG_TOSHIBA_RBTX4939) += arch/mips/txx9/rbtx4939/
+#
+# Cavium Octeon
+#
+core-$(CONFIG_CPU_CAVIUM_OCTEON) += arch/mips/cavium-octeon/
+cflags-$(CONFIG_CPU_CAVIUM_OCTEON) += -I$(srctree)/arch/mips/include/asm/mach-cavium-octeon
+core-$(CONFIG_CPU_CAVIUM_OCTEON) += arch/mips/cavium-octeon/executive/
+ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
+load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff84100000
+else
+load-$(CONFIG_CPU_CAVIUM_OCTEON) += 0xffffffff81100000
+endif
+
cflags-y += -I$(srctree)/arch/mips/include/asm/mach-generic
drivers-$(CONFIG_PCI) += arch/mips/pci/
diff --git a/arch/mips/alchemy/Kconfig b/arch/mips/alchemy/Kconfig
index e4a057d..7f8ef13 100644
--- a/arch/mips/alchemy/Kconfig
+++ b/arch/mips/alchemy/Kconfig
@@ -128,9 +128,10 @@ config SOC_AU1200
config SOC_AU1X00
bool
select 64BIT_PHYS_ADDR
- select CEVT_R4K
- select CSRC_R4K
+ select CEVT_R4K_LIB
+ select CSRC_R4K_LIB
select IRQ_CPU
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_APM_EMULATION
+ select GENERIC_HARDIRQS_NO__DO_IRQ
diff --git a/arch/mips/alchemy/common/Makefile b/arch/mips/alchemy/common/Makefile
index df48fd6..d50d476 100644
--- a/arch/mips/alchemy/common/Makefile
+++ b/arch/mips/alchemy/common/Makefile
@@ -6,8 +6,8 @@
#
obj-y += prom.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 gpio.o
+ clocks.o platform.o power.o setup.o \
+ sleeper.o dma.o dbdma.o gpio.o
obj-$(CONFIG_PCI) += pci.o
diff --git a/arch/mips/alchemy/common/au1xxx_irqmap.c b/arch/mips/alchemy/common/au1xxx_irqmap.c
deleted file mode 100644
index c7ca159..0000000
--- a/arch/mips/alchemy/common/au1xxx_irqmap.c
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- * Au1xxx processor specific IRQ tables
- *
- * Copyright 2004 Embedded Edge, LLC
- * dan@embeddededge.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/kernel.h>
-
-#include <au1000.h>
-
-/* The IC0 interrupt table. This is processor, rather than
- * board dependent, so no reason to keep this info in the board
- * dependent files.
- *
- * Careful if you change match 2 request!
- * The interrupt handler is called directly from the low level dispatch code.
- */
-struct au1xxx_irqmap __initdata au1xxx_ic0_map[] = {
-
-#if defined(CONFIG_SOC_AU1000)
- { AU1000_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_UART2_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 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 },
- { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
- { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1000_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
-
-#elif defined(CONFIG_SOC_AU1500)
-
- { AU1500_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
- { AU1000_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
- { AU1500_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
- { AU1000_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
- { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 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 },
- { AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
- { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1500_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1500_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
-
-#elif defined(CONFIG_SOC_AU1100)
-
- { AU1100_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1100_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1100_SD_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1100_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_SSI0_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_SSI1_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+1, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+2, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+3, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+4, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+5, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+6, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_DMA_INT_BASE+7, INTC_INT_HIGH_LEVEL, 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 },
- { AU1000_IRDA_TX_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_IRDA_RX_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_USB_DEV_REQ_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_USB_DEV_SUS_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1000_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
- { AU1000_ACSYNC_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1100_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
- /* { AU1000_GPIO215_208_INT, INTC_INT_HIGH_LEVEL, 0 }, */
- { AU1100_LCD_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1000_AC97C_INT, INTC_INT_RISE_EDGE, 0 },
-
-#elif defined(CONFIG_SOC_AU1550)
-
- { AU1550_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1550_PCI_INTA, INTC_INT_LOW_LEVEL, 0 },
- { AU1550_PCI_INTB, INTC_INT_LOW_LEVEL, 0 },
- { AU1550_DDMA_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1550_CRYPTO_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1550_PCI_INTC, INTC_INT_LOW_LEVEL, 0 },
- { AU1550_PCI_INTD, INTC_INT_LOW_LEVEL, 0 },
- { AU1550_PCI_RST_INT, INTC_INT_LOW_LEVEL, 0 },
- { AU1550_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1550_UART3_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1550_PSC0_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1550_PSC1_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1550_PSC2_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1550_PSC3_INT, INTC_INT_HIGH_LEVEL, 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 },
- { AU1550_USB_HOST_INT, INTC_INT_LOW_LEVEL, 0 },
- { AU1550_MAC0_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1550_MAC1_DMA_INT, INTC_INT_HIGH_LEVEL, 0 },
-
-#elif defined(CONFIG_SOC_AU1200)
-
- { AU1200_UART0_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1200_SWT_INT, INTC_INT_RISE_EDGE, 0 },
- { AU1200_SD_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1200_DDMA_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1200_MAE_BE_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1200_UART1_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1200_MAE_FE_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1200_PSC0_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1200_PSC1_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1200_AES_INT, INTC_INT_HIGH_LEVEL, 0 },
- { AU1200_CAMERA_INT, INTC_INT_HIGH_LEVEL, 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 },
- { AU1200_MAE_BOTH_INT, INTC_INT_HIGH_LEVEL, 0 },
-
-#else
-#error "Error: Unknown Alchemy SOC"
-#endif
-
-};
-
-int __initdata au1xxx_ic0_nr_irqs = ARRAY_SIZE(au1xxx_ic0_map);
diff --git a/arch/mips/alchemy/common/clocks.c b/arch/mips/alchemy/common/clocks.c
index 043429d..d899185 100644
--- a/arch/mips/alchemy/common/clocks.c
+++ b/arch/mips/alchemy/common/clocks.c
@@ -27,12 +27,21 @@
*/
#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <asm/time.h>
#include <asm/mach-au1x00/au1000.h>
+/*
+ * I haven't found anyone that doesn't use a 12 MHz source clock,
+ * but just in case.....
+ */
+#define AU1000_SRC_CLK 12000000
+
static unsigned int au1x00_clock; /* Hz */
-static unsigned int lcd_clock; /* KHz */
static unsigned long uart_baud_base;
+static DEFINE_SPINLOCK(time_lock);
+
/*
* Set the au1000_clock
*/
@@ -63,31 +72,45 @@ void set_au1x00_uart_baud_base(unsigned long new_baud_base)
}
/*
- * Calculate the Au1x00's LCD clock based on the current
- * cpu clock and the system bus clock, and try to keep it
- * below 40 MHz (the Pb1000 board can lock-up if the LCD
- * clock is over 40 MHz).
+ * We read the real processor speed from the PLL. This is important
+ * because it is more accurate than computing it from the 32 KHz
+ * counter, if it exists. If we don't have an accurate processor
+ * speed, all of the peripherals that derive their clocks based on
+ * this advertised speed will introduce error and sometimes not work
+ * properly. This function is futher convoluted to still allow configurations
+ * to do that in case they have really, really old silicon with a
+ * write-only PLL register. -- Dan
*/
-void set_au1x00_lcd_clock(void)
+unsigned long au1xxx_calc_clock(void)
{
- unsigned int static_cfg0;
- unsigned int sys_busclk = (get_au1x00_speed() / 1000) /
- ((int)(au_readl(SYS_POWERCTRL) & 0x03) + 2);
+ unsigned long cpu_speed;
+ unsigned long flags;
- static_cfg0 = au_readl(MEM_STCFG0);
+ spin_lock_irqsave(&time_lock, flags);
- if (static_cfg0 & (1 << 11))
- lcd_clock = sys_busclk / 5; /* note: BCLK switching fails with D5 */
+ /*
+ * On early Au1000, sys_cpupll was write-only. Since these
+ * silicon versions of Au1000 are not sold by AMD, we don't bend
+ * over backwards trying to determine the frequency.
+ */
+ if (au1xxx_cpu_has_pll_wo())
+#ifdef CONFIG_SOC_AU1000_FREQUENCY
+ cpu_speed = CONFIG_SOC_AU1000_FREQUENCY;
+#else
+ cpu_speed = 396000000;
+#endif
else
- lcd_clock = sys_busclk / 4;
+ cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK;
- if (lcd_clock > 50000) /* Epson MAX */
- printk(KERN_WARNING "warning: LCD clock too high (%u KHz)\n",
- lcd_clock);
-}
+ /* On Alchemy CPU:counter ratio is 1:1 */
+ mips_hpt_frequency = cpu_speed;
+ /* Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) */
+ set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)
+ & 0x03) + 2) * 16));
-unsigned int get_au1x00_lcd_clock(void)
-{
- return lcd_clock;
+ spin_unlock_irqrestore(&time_lock, flags);
+
+ set_au1x00_speed(cpu_speed);
+
+ return cpu_speed;
}
-EXPORT_SYMBOL(get_au1x00_lcd_clock);
diff --git a/arch/mips/alchemy/common/cputable.c b/arch/mips/alchemy/common/cputable.c
deleted file mode 100644
index ba6430b..0000000
--- a/arch/mips/alchemy/common/cputable.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * arch/mips/au1000/common/cputable.c
- *
- * Copyright (C) 2004 Dan Malek (dan@embeddededge.com)
- * Copied from PowerPC and updated for Alchemy Au1xxx processors.
- *
- * 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.
- */
-
-#include <asm/mach-au1x00/au1000.h>
-
-struct cpu_spec *cur_cpu_spec[NR_CPUS];
-
-/* With some thought, we can probably use the mask to reduce the
- * size of the table.
- */
-struct cpu_spec cpu_specs[] = {
- { 0xffffffff, 0x00030100, "Au1000 DA", 1, 0, 1 },
- { 0xffffffff, 0x00030201, "Au1000 HA", 1, 0, 1 },
- { 0xffffffff, 0x00030202, "Au1000 HB", 1, 0, 1 },
- { 0xffffffff, 0x00030203, "Au1000 HC", 1, 1, 0 },
- { 0xffffffff, 0x00030204, "Au1000 HD", 1, 1, 0 },
- { 0xffffffff, 0x01030200, "Au1500 AB", 1, 1, 0 },
- { 0xffffffff, 0x01030201, "Au1500 AC", 0, 1, 0 },
- { 0xffffffff, 0x01030202, "Au1500 AD", 0, 1, 0 },
- { 0xffffffff, 0x02030200, "Au1100 AB", 1, 1, 0 },
- { 0xffffffff, 0x02030201, "Au1100 BA", 1, 1, 0 },
- { 0xffffffff, 0x02030202, "Au1100 BC", 1, 1, 0 },
- { 0xffffffff, 0x02030203, "Au1100 BD", 0, 1, 0 },
- { 0xffffffff, 0x02030204, "Au1100 BE", 0, 1, 0 },
- { 0xffffffff, 0x03030200, "Au1550 AA", 0, 1, 0 },
- { 0xffffffff, 0x04030200, "Au1200 AB", 0, 0, 0 },
- { 0xffffffff, 0x04030201, "Au1200 AC", 1, 0, 0 },
- { 0x00000000, 0x00000000, "Unknown Au1xxx", 1, 0, 0 }
-};
-
-void set_cpuspec(void)
-{
- struct cpu_spec *sp;
- u32 prid;
-
- prid = read_c0_prid();
- sp = cpu_specs;
- while ((prid & sp->prid_mask) != sp->prid_value)
- sp++;
- cur_cpu_spec[0] = sp;
-}
diff --git a/arch/mips/alchemy/common/dbdma.c b/arch/mips/alchemy/common/dbdma.c
index 601ee91..3ab6d80 100644
--- a/arch/mips/alchemy/common/dbdma.c
+++ b/arch/mips/alchemy/common/dbdma.c
@@ -174,6 +174,11 @@ static dbdev_tab_t dbdev_tab[] = {
#define DBDEV_TAB_SIZE ARRAY_SIZE(dbdev_tab)
+#ifdef CONFIG_PM
+static u32 au1xxx_dbdma_pm_regs[NUM_DBDMA_CHANS + 1][8];
+#endif
+
+
static chan_tab_t *chan_tab_ptr[NUM_DBDMA_CHANS];
static dbdev_tab_t *find_dbdev_id(u32 id)
@@ -975,4 +980,64 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr)
return nbytes;
}
+#ifdef CONFIG_PM
+void au1xxx_dbdma_suspend(void)
+{
+ int i;
+ u32 addr;
+
+ addr = DDMA_GLOBAL_BASE;
+ au1xxx_dbdma_pm_regs[0][0] = au_readl(addr + 0x00);
+ au1xxx_dbdma_pm_regs[0][1] = au_readl(addr + 0x04);
+ au1xxx_dbdma_pm_regs[0][2] = au_readl(addr + 0x08);
+ au1xxx_dbdma_pm_regs[0][3] = au_readl(addr + 0x0c);
+
+ /* save channel configurations */
+ for (i = 1, addr = DDMA_CHANNEL_BASE; i < NUM_DBDMA_CHANS; i++) {
+ au1xxx_dbdma_pm_regs[i][0] = au_readl(addr + 0x00);
+ au1xxx_dbdma_pm_regs[i][1] = au_readl(addr + 0x04);
+ au1xxx_dbdma_pm_regs[i][2] = au_readl(addr + 0x08);
+ au1xxx_dbdma_pm_regs[i][3] = au_readl(addr + 0x0c);
+ au1xxx_dbdma_pm_regs[i][4] = au_readl(addr + 0x10);
+ au1xxx_dbdma_pm_regs[i][5] = au_readl(addr + 0x14);
+ au1xxx_dbdma_pm_regs[i][6] = au_readl(addr + 0x18);
+
+ /* halt channel */
+ au_writel(au1xxx_dbdma_pm_regs[i][0] & ~1, addr + 0x00);
+ au_sync();
+ while (!(au_readl(addr + 0x14) & 1))
+ au_sync();
+
+ addr += 0x100; /* next channel base */
+ }
+ /* disable channel interrupts */
+ au_writel(0, DDMA_GLOBAL_BASE + 0x0c);
+ au_sync();
+}
+
+void au1xxx_dbdma_resume(void)
+{
+ int i;
+ u32 addr;
+
+ addr = DDMA_GLOBAL_BASE;
+ au_writel(au1xxx_dbdma_pm_regs[0][0], addr + 0x00);
+ au_writel(au1xxx_dbdma_pm_regs[0][1], addr + 0x04);
+ au_writel(au1xxx_dbdma_pm_regs[0][2], addr + 0x08);
+ au_writel(au1xxx_dbdma_pm_regs[0][3], addr + 0x0c);
+
+ /* restore channel configurations */
+ for (i = 1, addr = DDMA_CHANNEL_BASE; i < NUM_DBDMA_CHANS; i++) {
+ au_writel(au1xxx_dbdma_pm_regs[i][0], addr + 0x00);
+ au_writel(au1xxx_dbdma_pm_regs[i][1], addr + 0x04);
+ au_writel(au1xxx_dbdma_pm_regs[i][2], addr + 0x08);
+ au_writel(au1xxx_dbdma_pm_regs[i][3], addr + 0x0c);
+ au_writel(au1xxx_dbdma_pm_regs[i][4], addr + 0x10);
+ au_writel(au1xxx_dbdma_pm_regs[i][5], addr + 0x14);
+ au_writel(au1xxx_dbdma_pm_regs[i][6], addr + 0x18);
+ au_sync();
+ addr += 0x100; /* next channel base */
+ }
+}
+#endif /* CONFIG_PM */
#endif /* defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200) */
diff --git a/arch/mips/alchemy/common/irq.c b/arch/mips/alchemy/common/irq.c
index 40c6cec..c88c821 100644
--- a/arch/mips/alchemy/common/irq.c
+++ b/arch/mips/alchemy/common/irq.c
@@ -24,6 +24,7 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+
#include <linux/bitops.h>
#include <linux/init.h>
#include <linux/interrupt.h>
@@ -36,15 +37,172 @@
#include <asm/mach-pb1x00/pb1000.h>
#endif
-#define EXT_INTC0_REQ0 2 /* IP 2 */
-#define EXT_INTC0_REQ1 3 /* IP 3 */
-#define EXT_INTC1_REQ0 4 /* IP 4 */
-#define EXT_INTC1_REQ1 5 /* IP 5 */
-#define MIPS_TIMER_IP 7 /* IP 7 */
-
-void (*board_init_irq)(void) __initdata = NULL;
+static int au1x_ic_settype(unsigned int irq, unsigned int flow_type);
+
+/* per-processor fixed function irqs */
+struct au1xxx_irqmap au1xxx_ic0_map[] __initdata = {
+
+#if defined(CONFIG_SOC_AU1000)
+ { AU1000_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_UART2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
+ { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
+
+#elif defined(CONFIG_SOC_AU1500)
+
+ { AU1500_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1000_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1500_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1000_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
+ { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1500_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1500_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
+
+#elif defined(CONFIG_SOC_AU1100)
+
+ { AU1100_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_SSI0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_SSI1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+1, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+2, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+3, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+4, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+5, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+6, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_DMA_INT_BASE+7, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
+ { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_IRDA_TX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_IRDA_RX_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1000_ACSYNC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1100_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1100_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_AC97C_INT, IRQ_TYPE_EDGE_RISING, 0 },
+
+#elif defined(CONFIG_SOC_AU1550)
+
+ { AU1550_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_PCI_INTA, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1550_PCI_INTB, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1550_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_CRYPTO_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_PCI_INTC, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1550_PCI_INTD, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1550_PCI_RST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1550_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_UART3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_PSC2_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_PSC3_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
+ { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1550_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1550_USB_DEV_REQ_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_USB_DEV_SUS_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1550_USB_HOST_INT, IRQ_TYPE_LEVEL_LOW, 0 },
+ { AU1550_MAC0_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1550_MAC1_DMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+
+#elif defined(CONFIG_SOC_AU1200)
+
+ { AU1200_UART0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_SWT_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1200_SD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_DDMA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_MAE_BE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_UART1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_MAE_FE_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_PSC0_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_PSC1_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_AES_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_CAMERA_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1000_TOY_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_TOY_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_TOY_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_TOY_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 1 },
+ { AU1000_RTC_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_MATCH0_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_MATCH1_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1000_RTC_MATCH2_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1200_NAND_INT, IRQ_TYPE_EDGE_RISING, 0 },
+ { AU1200_USB_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_LCD_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+ { AU1200_MAE_BOTH_INT, IRQ_TYPE_LEVEL_HIGH, 0 },
+
+#else
+#error "Error: Unknown Alchemy SOC"
+#endif
+};
-static DEFINE_SPINLOCK(irq_lock);
#ifdef CONFIG_PM
@@ -130,67 +288,47 @@ void restore_au1xxx_intctl(void)
#endif /* CONFIG_PM */
-inline void local_enable_irq(unsigned int irq_nr)
+static void au1x_ic0_unmask(unsigned int irq_nr)
{
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
-
- if (bit >= 32) {
- au_writel(1 << (bit - 32), IC1_MASKSET);
- au_writel(1 << (bit - 32), IC1_WAKESET);
- } else {
- au_writel(1 << bit, IC0_MASKSET);
- au_writel(1 << bit, IC0_WAKESET);
- }
+ au_writel(1 << bit, IC0_MASKSET);
+ au_writel(1 << bit, IC0_WAKESET);
au_sync();
}
-
-inline void local_disable_irq(unsigned int irq_nr)
+static void au1x_ic1_unmask(unsigned int irq_nr)
{
- unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
+ unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
+ au_writel(1 << bit, IC1_MASKSET);
+ au_writel(1 << bit, IC1_WAKESET);
- if (bit >= 32) {
- au_writel(1 << (bit - 32), IC1_MASKCLR);
- au_writel(1 << (bit - 32), IC1_WAKECLR);
- } else {
- au_writel(1 << bit, IC0_MASKCLR);
- au_writel(1 << bit, IC0_WAKECLR);
- }
+/* very hacky. does the pb1000 cpld auto-disable this int?
+ * nowhere in the current kernel sources is it disabled. --mlau
+ */
+#if defined(CONFIG_MIPS_PB1000)
+ if (irq_nr == AU1000_GPIO_15)
+ au_writel(0x4000, PB1000_MDR); /* enable int */
+#endif
au_sync();
}
-
-static inline void mask_and_ack_rise_edge_irq(unsigned int irq_nr)
+static void au1x_ic0_mask(unsigned int irq_nr)
{
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
-
- if (bit >= 32) {
- au_writel(1 << (bit - 32), IC1_RISINGCLR);
- au_writel(1 << (bit - 32), IC1_MASKCLR);
- } else {
- au_writel(1 << bit, IC0_RISINGCLR);
- au_writel(1 << bit, IC0_MASKCLR);
- }
+ au_writel(1 << bit, IC0_MASKCLR);
+ au_writel(1 << bit, IC0_WAKECLR);
au_sync();
}
-
-static inline void mask_and_ack_fall_edge_irq(unsigned int irq_nr)
+static void au1x_ic1_mask(unsigned int irq_nr)
{
- unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
-
- if (bit >= 32) {
- au_writel(1 << (bit - 32), IC1_FALLINGCLR);
- au_writel(1 << (bit - 32), IC1_MASKCLR);
- } else {
- au_writel(1 << bit, IC0_FALLINGCLR);
- au_writel(1 << bit, IC0_MASKCLR);
- }
+ unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
+ au_writel(1 << bit, IC1_MASKCLR);
+ au_writel(1 << bit, IC1_WAKECLR);
au_sync();
}
-
-static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr)
+static void au1x_ic0_ack(unsigned int irq_nr)
{
unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
@@ -198,349 +336,229 @@ static inline void mask_and_ack_either_edge_irq(unsigned int irq_nr)
* This may assume that we don't get interrupts from
* both edges at once, or if we do, that we don't care.
*/
- if (bit >= 32) {
- au_writel(1 << (bit - 32), IC1_FALLINGCLR);
- au_writel(1 << (bit - 32), IC1_RISINGCLR);
- au_writel(1 << (bit - 32), IC1_MASKCLR);
- } else {
- au_writel(1 << bit, IC0_FALLINGCLR);
- au_writel(1 << bit, IC0_RISINGCLR);
- au_writel(1 << bit, IC0_MASKCLR);
- }
+ au_writel(1 << bit, IC0_FALLINGCLR);
+ au_writel(1 << bit, IC0_RISINGCLR);
au_sync();
}
-static inline void mask_and_ack_level_irq(unsigned int irq_nr)
+static void au1x_ic1_ack(unsigned int irq_nr)
{
- local_disable_irq(irq_nr);
- au_sync();
-#if defined(CONFIG_MIPS_PB1000)
- if (irq_nr == AU1000_GPIO_15) {
- au_writel(0x8000, PB1000_MDR); /* ack int */
- au_sync();
- }
-#endif
-}
-
-static void end_irq(unsigned int irq_nr)
-{
- if (!(irq_desc[irq_nr].status & (IRQ_DISABLED | IRQ_INPROGRESS)))
- local_enable_irq(irq_nr);
+ unsigned int bit = irq_nr - AU1000_INTC1_INT_BASE;
-#if defined(CONFIG_MIPS_PB1000)
- if (irq_nr == AU1000_GPIO_15) {
- au_writel(0x4000, PB1000_MDR); /* enable int */
- au_sync();
- }
-#endif
+ /*
+ * This may assume that we don't get interrupts from
+ * both edges at once, or if we do, that we don't care.
+ */
+ au_writel(1 << bit, IC1_FALLINGCLR);
+ au_writel(1 << bit, IC1_RISINGCLR);
+ au_sync();
}
-unsigned long save_local_and_disable(int controller)
+static int au1x_ic1_setwake(unsigned int irq, unsigned int on)
{
- int i;
- unsigned long flags, mask;
-
- spin_lock_irqsave(&irq_lock, flags);
- if (controller) {
- mask = au_readl(IC1_MASKSET);
- for (i = 32; i < 64; i++)
- local_disable_irq(i);
- } else {
- mask = au_readl(IC0_MASKSET);
- for (i = 0; i < 32; i++)
- local_disable_irq(i);
- }
- spin_unlock_irqrestore(&irq_lock, flags);
-
- return mask;
-}
+ unsigned int bit = irq - AU1000_INTC1_INT_BASE;
+ unsigned long wakemsk, flags;
-void restore_local_and_enable(int controller, unsigned long mask)
-{
- int i;
- unsigned long flags, new_mask;
-
- spin_lock_irqsave(&irq_lock, flags);
- for (i = 0; i < 32; i++)
- if (mask & (1 << i)) {
- if (controller)
- local_enable_irq(i + 32);
- else
- local_enable_irq(i);
- }
+ /* only GPIO 0-7 can act as wakeup source: */
+ if ((irq < AU1000_GPIO_0) || (irq > AU1000_GPIO_7))
+ return -EINVAL;
- if (controller)
- new_mask = au_readl(IC1_MASKSET);
+ local_irq_save(flags);
+ wakemsk = au_readl(SYS_WAKEMSK);
+ if (on)
+ wakemsk |= 1 << bit;
else
- new_mask = au_readl(IC0_MASKSET);
+ wakemsk &= ~(1 << bit);
+ au_writel(wakemsk, SYS_WAKEMSK);
+ au_sync();
+ local_irq_restore(flags);
- spin_unlock_irqrestore(&irq_lock, flags);
+ return 0;
}
-
-static struct irq_chip rise_edge_irq_type = {
- .name = "Au1000 Rise Edge",
- .ack = mask_and_ack_rise_edge_irq,
- .mask = local_disable_irq,
- .mask_ack = mask_and_ack_rise_edge_irq,
- .unmask = local_enable_irq,
- .end = end_irq,
-};
-
-static struct irq_chip fall_edge_irq_type = {
- .name = "Au1000 Fall Edge",
- .ack = mask_and_ack_fall_edge_irq,
- .mask = local_disable_irq,
- .mask_ack = mask_and_ack_fall_edge_irq,
- .unmask = local_enable_irq,
- .end = end_irq,
-};
-
-static struct irq_chip either_edge_irq_type = {
- .name = "Au1000 Rise or Fall Edge",
- .ack = mask_and_ack_either_edge_irq,
- .mask = local_disable_irq,
- .mask_ack = mask_and_ack_either_edge_irq,
- .unmask = local_enable_irq,
- .end = end_irq,
+/*
+ * irq_chips for both ICs; this way the mask handlers can be
+ * as short as possible.
+ *
+ * NOTE: the ->ack() callback is used by the handle_edge_irq
+ * flowhandler only, the ->mask_ack() one by handle_level_irq,
+ * so no need for an irq_chip for each type of irq (level/edge).
+ */
+static struct irq_chip au1x_ic0_chip = {
+ .name = "Alchemy-IC0",
+ .ack = au1x_ic0_ack, /* edge */
+ .mask = au1x_ic0_mask,
+ .mask_ack = au1x_ic0_mask, /* level */
+ .unmask = au1x_ic0_unmask,
+ .set_type = au1x_ic_settype,
};
-static struct irq_chip level_irq_type = {
- .name = "Au1000 Level",
- .ack = mask_and_ack_level_irq,
- .mask = local_disable_irq,
- .mask_ack = mask_and_ack_level_irq,
- .unmask = local_enable_irq,
- .end = end_irq,
+static struct irq_chip au1x_ic1_chip = {
+ .name = "Alchemy-IC1",
+ .ack = au1x_ic1_ack, /* edge */
+ .mask = au1x_ic1_mask,
+ .mask_ack = au1x_ic1_mask, /* level */
+ .unmask = au1x_ic1_unmask,
+ .set_type = au1x_ic_settype,
+ .set_wake = au1x_ic1_setwake,
};
-static void __init setup_local_irq(unsigned int irq_nr, int type, int int_req)
+static int au1x_ic_settype(unsigned int irq, unsigned int flow_type)
{
- unsigned int bit = irq_nr - AU1000_INTC0_INT_BASE;
-
- if (irq_nr > AU1000_MAX_INTR)
- return;
-
- /* Config2[n], Config1[n], Config0[n] */
- if (bit >= 32) {
- switch (type) {
- case INTC_INT_RISE_EDGE: /* 0:0:1 */
- au_writel(1 << (bit - 32), IC1_CFG2CLR);
- au_writel(1 << (bit - 32), IC1_CFG1CLR);
- au_writel(1 << (bit - 32), IC1_CFG0SET);
- set_irq_chip(irq_nr, &rise_edge_irq_type);
- break;
- case INTC_INT_FALL_EDGE: /* 0:1:0 */
- au_writel(1 << (bit - 32), IC1_CFG2CLR);
- au_writel(1 << (bit - 32), IC1_CFG1SET);
- au_writel(1 << (bit - 32), IC1_CFG0CLR);
- set_irq_chip(irq_nr, &fall_edge_irq_type);
- break;
- case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
- au_writel(1 << (bit - 32), IC1_CFG2CLR);
- au_writel(1 << (bit - 32), IC1_CFG1SET);
- au_writel(1 << (bit - 32), IC1_CFG0SET);
- set_irq_chip(irq_nr, &either_edge_irq_type);
- break;
- case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
- au_writel(1 << (bit - 32), IC1_CFG2SET);
- au_writel(1 << (bit - 32), IC1_CFG1CLR);
- au_writel(1 << (bit - 32), IC1_CFG0SET);
- set_irq_chip(irq_nr, &level_irq_type);
- break;
- case INTC_INT_LOW_LEVEL: /* 1:1:0 */
- au_writel(1 << (bit - 32), IC1_CFG2SET);
- au_writel(1 << (bit - 32), IC1_CFG1SET);
- au_writel(1 << (bit - 32), IC1_CFG0CLR);
- set_irq_chip(irq_nr, &level_irq_type);
- break;
- case INTC_INT_DISABLED: /* 0:0:0 */
- au_writel(1 << (bit - 32), IC1_CFG0CLR);
- au_writel(1 << (bit - 32), IC1_CFG1CLR);
- au_writel(1 << (bit - 32), IC1_CFG2CLR);
- break;
- default: /* disable the interrupt */
- printk(KERN_WARNING "unexpected int type %d (irq %d)\n",
- type, irq_nr);
- au_writel(1 << (bit - 32), IC1_CFG0CLR);
- au_writel(1 << (bit - 32), IC1_CFG1CLR);
- au_writel(1 << (bit - 32), IC1_CFG2CLR);
- return;
- }
- if (int_req) /* assign to interrupt request 1 */
- au_writel(1 << (bit - 32), IC1_ASSIGNCLR);
- else /* assign to interrupt request 0 */
- au_writel(1 << (bit - 32), IC1_ASSIGNSET);
- au_writel(1 << (bit - 32), IC1_SRCSET);
- au_writel(1 << (bit - 32), IC1_MASKCLR);
- au_writel(1 << (bit - 32), IC1_WAKECLR);
+ struct irq_chip *chip;
+ unsigned long icr[6];
+ unsigned int bit, ic;
+ int ret;
+
+ if (irq >= AU1000_INTC1_INT_BASE) {
+ bit = irq - AU1000_INTC1_INT_BASE;
+ chip = &au1x_ic1_chip;
+ ic = 1;
} else {
- switch (type) {
- case INTC_INT_RISE_EDGE: /* 0:0:1 */
- au_writel(1 << bit, IC0_CFG2CLR);
- au_writel(1 << bit, IC0_CFG1CLR);
- au_writel(1 << bit, IC0_CFG0SET);
- set_irq_chip(irq_nr, &rise_edge_irq_type);
- break;
- case INTC_INT_FALL_EDGE: /* 0:1:0 */
- au_writel(1 << bit, IC0_CFG2CLR);
- au_writel(1 << bit, IC0_CFG1SET);
- au_writel(1 << bit, IC0_CFG0CLR);
- set_irq_chip(irq_nr, &fall_edge_irq_type);
- break;
- case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */
- au_writel(1 << bit, IC0_CFG2CLR);
- au_writel(1 << bit, IC0_CFG1SET);
- au_writel(1 << bit, IC0_CFG0SET);
- set_irq_chip(irq_nr, &either_edge_irq_type);
- break;
- case INTC_INT_HIGH_LEVEL: /* 1:0:1 */
- au_writel(1 << bit, IC0_CFG2SET);
- au_writel(1 << bit, IC0_CFG1CLR);
- au_writel(1 << bit, IC0_CFG0SET);
- set_irq_chip(irq_nr, &level_irq_type);
- break;
- case INTC_INT_LOW_LEVEL: /* 1:1:0 */
- au_writel(1 << bit, IC0_CFG2SET);
- au_writel(1 << bit, IC0_CFG1SET);
- au_writel(1 << bit, IC0_CFG0CLR);
- set_irq_chip(irq_nr, &level_irq_type);
- break;
- case INTC_INT_DISABLED: /* 0:0:0 */
- au_writel(1 << bit, IC0_CFG0CLR);
- au_writel(1 << bit, IC0_CFG1CLR);
- au_writel(1 << bit, IC0_CFG2CLR);
- break;
- default: /* disable the interrupt */
- printk(KERN_WARNING "unexpected int type %d (irq %d)\n",
- type, irq_nr);
- au_writel(1 << bit, IC0_CFG0CLR);
- au_writel(1 << bit, IC0_CFG1CLR);
- au_writel(1 << bit, IC0_CFG2CLR);
- return;
- }
- if (int_req) /* assign to interrupt request 1 */
- au_writel(1 << bit, IC0_ASSIGNCLR);
- else /* assign to interrupt request 0 */
- au_writel(1 << bit, IC0_ASSIGNSET);
- au_writel(1 << bit, IC0_SRCSET);
- au_writel(1 << bit, IC0_MASKCLR);
- au_writel(1 << bit, IC0_WAKECLR);
+ bit = irq - AU1000_INTC0_INT_BASE;
+ chip = &au1x_ic0_chip;
+ ic = 0;
+ }
+
+ if (bit > 31)
+ return -EINVAL;
+
+ icr[0] = ic ? IC1_CFG0SET : IC0_CFG0SET;
+ icr[1] = ic ? IC1_CFG1SET : IC0_CFG1SET;
+ icr[2] = ic ? IC1_CFG2SET : IC0_CFG2SET;
+ icr[3] = ic ? IC1_CFG0CLR : IC0_CFG0CLR;
+ icr[4] = ic ? IC1_CFG1CLR : IC0_CFG1CLR;
+ icr[5] = ic ? IC1_CFG2CLR : IC0_CFG2CLR;
+
+ ret = 0;
+
+ switch (flow_type) { /* cfgregs 2:1:0 */
+ case IRQ_TYPE_EDGE_RISING: /* 0:0:1 */
+ au_writel(1 << bit, icr[5]);
+ au_writel(1 << bit, icr[4]);
+ au_writel(1 << bit, icr[0]);
+ set_irq_chip_and_handler_name(irq, chip,
+ handle_edge_irq, "riseedge");
+ break;
+ case IRQ_TYPE_EDGE_FALLING: /* 0:1:0 */
+ au_writel(1 << bit, icr[5]);
+ au_writel(1 << bit, icr[1]);
+ au_writel(1 << bit, icr[3]);
+ set_irq_chip_and_handler_name(irq, chip,
+ handle_edge_irq, "falledge");
+ break;
+ case IRQ_TYPE_EDGE_BOTH: /* 0:1:1 */
+ au_writel(1 << bit, icr[5]);
+ au_writel(1 << bit, icr[1]);
+ au_writel(1 << bit, icr[0]);
+ set_irq_chip_and_handler_name(irq, chip,
+ handle_edge_irq, "bothedge");
+ break;
+ case IRQ_TYPE_LEVEL_HIGH: /* 1:0:1 */
+ au_writel(1 << bit, icr[2]);
+ au_writel(1 << bit, icr[4]);
+ au_writel(1 << bit, icr[0]);
+ set_irq_chip_and_handler_name(irq, chip,
+ handle_level_irq, "hilevel");
+ break;
+ case IRQ_TYPE_LEVEL_LOW: /* 1:1:0 */
+ au_writel(1 << bit, icr[2]);
+ au_writel(1 << bit, icr[1]);
+ au_writel(1 << bit, icr[3]);
+ set_irq_chip_and_handler_name(irq, chip,
+ handle_level_irq, "lowlevel");
+ break;
+ case IRQ_TYPE_NONE: /* 0:0:0 */
+ au_writel(1 << bit, icr[5]);
+ au_writel(1 << bit, icr[4]);
+ au_writel(1 << bit, icr[3]);
+ /* set at least chip so we can call set_irq_type() on it */
+ set_irq_chip(irq, chip);
+ break;
+ default:
+ ret = -EINVAL;
}
au_sync();
-}
-/*
- * Interrupts are nested. Even if an interrupt handler is registered
- * as "fast", we might get another interrupt before we return from
- * intcX_reqX_irqdispatch().
- */
+ return ret;
+}
-static void intc0_req0_irqdispatch(void)
+asmlinkage void plat_irq_dispatch(void)
{
- static unsigned long intc0_req0;
- unsigned int bit;
-
- intc0_req0 |= au_readl(IC0_REQ0INT);
+ unsigned int pending = read_c0_status() & read_c0_cause();
+ unsigned long s, off, bit;
- if (!intc0_req0)
+ if (pending & CAUSEF_IP7) {
+ do_IRQ(MIPS_CPU_IRQ_BASE + 7);
return;
-
+ } else if (pending & CAUSEF_IP2) {
+ s = IC0_REQ0INT;
+ off = AU1000_INTC0_INT_BASE;
+ } else if (pending & CAUSEF_IP3) {
+ s = IC0_REQ1INT;
+ off = AU1000_INTC0_INT_BASE;
+ } else if (pending & CAUSEF_IP4) {
+ s = IC1_REQ0INT;
+ off = AU1000_INTC1_INT_BASE;
+ } else if (pending & CAUSEF_IP5) {
+ s = IC1_REQ1INT;
+ off = AU1000_INTC1_INT_BASE;
+ } else
+ goto spurious;
+
+ bit = 0;
+ s = au_readl(s);
+ if (unlikely(!s)) {
+spurious:
+ spurious_interrupt();
+ return;
+ }
#ifdef AU1000_USB_DEV_REQ_INT
/*
* Because of the tight timing of SETUP token to reply
* transactions, the USB devices-side packet complete
* interrupt needs the highest priority.
*/
- if ((intc0_req0 & (1 << AU1000_USB_DEV_REQ_INT))) {
- intc0_req0 &= ~(1 << AU1000_USB_DEV_REQ_INT);
+ bit = 1 << (AU1000_USB_DEV_REQ_INT - AU1000_INTC0_INT_BASE);
+ if ((pending & CAUSEF_IP2) && (s & bit)) {
do_IRQ(AU1000_USB_DEV_REQ_INT);
return;
}
#endif
- bit = __ffs(intc0_req0);
- intc0_req0 &= ~(1 << bit);
- do_IRQ(AU1000_INTC0_INT_BASE + bit);
+ do_IRQ(__ffs(s) + off);
}
-
-static void intc0_req1_irqdispatch(void)
-{
- static unsigned long intc0_req1;
- unsigned int bit;
-
- intc0_req1 |= au_readl(IC0_REQ1INT);
-
- if (!intc0_req1)
- return;
-
- bit = __ffs(intc0_req1);
- intc0_req1 &= ~(1 << bit);
- do_IRQ(AU1000_INTC0_INT_BASE + bit);
-}
-
-
-/*
- * Interrupt Controller 1:
- * interrupts 32 - 63
- */
-static void intc1_req0_irqdispatch(void)
+/* setup edge/level and assign request 0/1 */
+void __init au1xxx_setup_irqmap(struct au1xxx_irqmap *map, int count)
{
- static unsigned long intc1_req0;
- unsigned int bit;
-
- intc1_req0 |= au_readl(IC1_REQ0INT);
-
- if (!intc1_req0)
- return;
-
- bit = __ffs(intc1_req0);
- intc1_req0 &= ~(1 << bit);
- do_IRQ(AU1000_INTC1_INT_BASE + bit);
-}
-
-
-static void intc1_req1_irqdispatch(void)
-{
- static unsigned long intc1_req1;
- unsigned int bit;
-
- intc1_req1 |= au_readl(IC1_REQ1INT);
-
- if (!intc1_req1)
- return;
-
- bit = __ffs(intc1_req1);
- intc1_req1 &= ~(1 << bit);
- do_IRQ(AU1000_INTC1_INT_BASE + bit);
-}
-
-asmlinkage void plat_irq_dispatch(void)
-{
- unsigned int pending = read_c0_status() & read_c0_cause();
+ unsigned int bit, irq_nr;
+
+ while (count--) {
+ irq_nr = map[count].im_irq;
+
+ if (((irq_nr < AU1000_INTC0_INT_BASE) ||
+ (irq_nr >= AU1000_INTC0_INT_BASE + 32)) &&
+ ((irq_nr < AU1000_INTC1_INT_BASE) ||
+ (irq_nr >= AU1000_INTC1_INT_BASE + 32)))
+ continue;
+
+ if (irq_nr >= AU1000_INTC1_INT_BASE) {
+ bit = irq_nr - AU1000_INTC1_INT_BASE;
+ if (map[count].im_request)
+ au_writel(1 << bit, IC1_ASSIGNCLR);
+ } else {
+ bit = irq_nr - AU1000_INTC0_INT_BASE;
+ if (map[count].im_request)
+ au_writel(1 << bit, IC0_ASSIGNCLR);
+ }
- if (pending & CAUSEF_IP7)
- do_IRQ(MIPS_CPU_IRQ_BASE + 7);
- else if (pending & CAUSEF_IP2)
- intc0_req0_irqdispatch();
- else if (pending & CAUSEF_IP3)
- intc0_req1_irqdispatch();
- else if (pending & CAUSEF_IP4)
- intc1_req0_irqdispatch();
- else if (pending & CAUSEF_IP5)
- intc1_req1_irqdispatch();
- else
- spurious_interrupt();
+ au1x_ic_settype(irq_nr, map[count].im_type);
+ }
}
void __init arch_init_irq(void)
{
int i;
- struct au1xxx_irqmap *imp;
- extern struct au1xxx_irqmap au1xxx_irq_map[];
- extern struct au1xxx_irqmap au1xxx_ic0_map[];
- extern int au1xxx_nr_irqs;
- extern int au1xxx_ic0_nr_irqs;
/*
* Initialize interrupt controllers to a safe state.
@@ -569,28 +587,25 @@ void __init arch_init_irq(void)
mips_cpu_irq_init();
- /*
- * Initialize IC0, which is fixed per processor.
+ /* register all 64 possible IC0+IC1 irq sources as type "none".
+ * Use set_irq_type() to set edge/level behaviour at runtime.
*/
- imp = au1xxx_ic0_map;
- for (i = 0; i < au1xxx_ic0_nr_irqs; i++) {
- setup_local_irq(imp->im_irq, imp->im_type, imp->im_request);
- imp++;
- }
+ for (i = AU1000_INTC0_INT_BASE;
+ (i < AU1000_INTC0_INT_BASE + 32); i++)
+ au1x_ic_settype(i, IRQ_TYPE_NONE);
+
+ for (i = AU1000_INTC1_INT_BASE;
+ (i < AU1000_INTC1_INT_BASE + 32); i++)
+ au1x_ic_settype(i, IRQ_TYPE_NONE);
/*
- * Now set up the irq mapping for the board.
+ * Initialize IC0, which is fixed per processor.
*/
- imp = au1xxx_irq_map;
- for (i = 0; i < au1xxx_nr_irqs; i++) {
- setup_local_irq(imp->im_irq, imp->im_type, imp->im_request);
- imp++;
- }
-
- set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3 | IE_IRQ4);
+ au1xxx_setup_irqmap(au1xxx_ic0_map, ARRAY_SIZE(au1xxx_ic0_map));
- /* Board specific IRQ initialization.
+ /* Boards can register additional (GPIO-based) IRQs.
*/
- if (board_init_irq)
- board_init_irq();
+ board_init_irq();
+
+ set_c0_status(IE_IRQ0 | IE_IRQ1 | IE_IRQ2 | IE_IRQ3);
}
diff --git a/arch/mips/alchemy/common/power.c b/arch/mips/alchemy/common/power.c
index bd854a6..6ab7b42 100644
--- a/arch/mips/alchemy/common/power.c
+++ b/arch/mips/alchemy/common/power.c
@@ -35,25 +35,12 @@
#include <linux/jiffies.h>
#include <asm/uaccess.h>
-#include <asm/cacheflush.h>
#include <asm/mach-au1x00/au1000.h>
-
-#ifdef CONFIG_PM
-
-#define DEBUG 1
-#ifdef DEBUG
-#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __func__, ## args)
-#else
-#define DPRINTK(fmt, args...)
+#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
+#include <asm/mach-au1x00/au1xxx_dbdma.h>
#endif
-static void au1000_calibrate_delay(void);
-
-extern unsigned long save_local_and_disable(int controller);
-extern void restore_local_and_enable(int controller, unsigned long mask);
-extern void local_enable_irq(unsigned int irq_nr);
-
-static DEFINE_SPINLOCK(pm_lock);
+#ifdef CONFIG_PM
/*
* We need to save/restore a bunch of core registers that are
@@ -65,29 +52,16 @@ static DEFINE_SPINLOCK(pm_lock);
* We only have to save/restore registers that aren't otherwise
* done as part of a driver pm_* function.
*/
-static unsigned int sleep_aux_pll_cntrl;
-static unsigned int sleep_cpu_pll_cntrl;
-static unsigned int sleep_pin_function;
-static unsigned int sleep_uart0_inten;
-static unsigned int sleep_uart0_fifoctl;
-static unsigned int sleep_uart0_linectl;
-static unsigned int sleep_uart0_clkdiv;
-static unsigned int sleep_uart0_enable;
-static unsigned int sleep_usbhost_enable;
-static unsigned int sleep_usbdev_enable;
-static unsigned int sleep_static_memctlr[4][3];
+static unsigned int sleep_uart0_inten;
+static unsigned int sleep_uart0_fifoctl;
+static unsigned int sleep_uart0_linectl;
+static unsigned int sleep_uart0_clkdiv;
+static unsigned int sleep_uart0_enable;
+static unsigned int sleep_usb[2];
+static unsigned int sleep_sys_clocks[5];
+static unsigned int sleep_sys_pinfunc;
+static unsigned int sleep_static_memctlr[4][3];
-/*
- * Define this to cause the value you write to /proc/sys/pm/sleep to
- * set the TOY timer for the amount of time you want to sleep.
- * This is done mainly for testing, but may be useful in other cases.
- * The value is number of 32KHz ticks to sleep.
- */
-#define SLEEP_TEST_TIMEOUT 1
-#ifdef SLEEP_TEST_TIMEOUT
-static int sleep_ticks;
-void wakeup_counter0_set(int ticks);
-#endif
static void save_core_regs(void)
{
@@ -105,31 +79,45 @@ static void save_core_regs(void)
sleep_uart0_linectl = au_readl(UART0_ADDR + UART_LCR);
sleep_uart0_clkdiv = au_readl(UART0_ADDR + UART_CLK);
sleep_uart0_enable = au_readl(UART0_ADDR + UART_MOD_CNTRL);
+ au_sync();
+#ifndef CONFIG_SOC_AU1200
/* Shutdown USB host/device. */
- sleep_usbhost_enable = au_readl(USB_HOST_CONFIG);
+ sleep_usb[0] = au_readl(USB_HOST_CONFIG);
/* There appears to be some undocumented reset register.... */
- au_writel(0, 0xb0100004); au_sync();
- au_writel(0, USB_HOST_CONFIG); au_sync();
+ au_writel(0, 0xb0100004);
+ au_sync();
+ au_writel(0, USB_HOST_CONFIG);
+ au_sync();
- sleep_usbdev_enable = au_readl(USBD_ENABLE);
- au_writel(0, USBD_ENABLE); au_sync();
+ sleep_usb[1] = au_readl(USBD_ENABLE);
+ au_writel(0, USBD_ENABLE);
+ au_sync();
+
+#else /* AU1200 */
+
+ /* enable access to OTG mmio so we can save OTG CAP/MUX.
+ * FIXME: write an OTG driver and move this stuff there!
+ */
+ au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4);
+ au_sync();
+ sleep_usb[0] = au_readl(0xb4020020); /* OTG_CAP */
+ sleep_usb[1] = au_readl(0xb4020024); /* OTG_MUX */
+#endif
/* Save interrupt controller state. */
save_au1xxx_intctl();
/* Clocks and PLLs. */
- sleep_aux_pll_cntrl = au_readl(SYS_AUXPLL);
+ sleep_sys_clocks[0] = au_readl(SYS_FREQCTRL0);
+ sleep_sys_clocks[1] = au_readl(SYS_FREQCTRL1);
+ sleep_sys_clocks[2] = au_readl(SYS_CLKSRC);
+ sleep_sys_clocks[3] = au_readl(SYS_CPUPLL);
+ sleep_sys_clocks[4] = au_readl(SYS_AUXPLL);
- /*
- * We don't really need to do this one, but unless we
- * write it again it won't have a valid value if we
- * happen to read it.
- */
- sleep_cpu_pll_cntrl = au_readl(SYS_CPUPLL);
-
- sleep_pin_function = au_readl(SYS_PINFUNC);
+ /* pin mux config */
+ sleep_sys_pinfunc = au_readl(SYS_PINFUNC);
/* Save the static memory controller configuration. */
sleep_static_memctlr[0][0] = au_readl(MEM_STCFG0);
@@ -144,16 +132,45 @@ static void save_core_regs(void)
sleep_static_memctlr[3][0] = au_readl(MEM_STCFG3);
sleep_static_memctlr[3][1] = au_readl(MEM_STTIME3);
sleep_static_memctlr[3][2] = au_readl(MEM_STADDR3);
+
+#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
+ au1xxx_dbdma_suspend();
+#endif
}
static void restore_core_regs(void)
{
- extern void restore_au1xxx_intctl(void);
- extern void wakeup_counter0_adjust(void);
+ /* restore clock configuration. Writing CPUPLL last will
+ * stall a bit and stabilize other clocks (unless this is
+ * one of those Au1000 with a write-only PLL, where we dont
+ * have a valid value)
+ */
+ au_writel(sleep_sys_clocks[0], SYS_FREQCTRL0);
+ au_writel(sleep_sys_clocks[1], SYS_FREQCTRL1);
+ au_writel(sleep_sys_clocks[2], SYS_CLKSRC);
+ au_writel(sleep_sys_clocks[4], SYS_AUXPLL);
+ if (!au1xxx_cpu_has_pll_wo())
+ au_writel(sleep_sys_clocks[3], SYS_CPUPLL);
+ au_sync();
- au_writel(sleep_aux_pll_cntrl, SYS_AUXPLL); au_sync();
- au_writel(sleep_cpu_pll_cntrl, SYS_CPUPLL); au_sync();
- au_writel(sleep_pin_function, SYS_PINFUNC); au_sync();
+ au_writel(sleep_sys_pinfunc, SYS_PINFUNC);
+ au_sync();
+
+#ifndef CONFIG_SOC_AU1200
+ au_writel(sleep_usb[0], USB_HOST_CONFIG);
+ au_writel(sleep_usb[1], USBD_ENABLE);
+ au_sync();
+#else
+ /* enable accces to OTG memory */
+ au_writel(au_readl(USB_MSR_BASE + 4) | (1 << 6), USB_MSR_BASE + 4);
+ au_sync();
+
+ /* restore OTG caps and port mux. */
+ au_writel(sleep_usb[0], 0xb4020020 + 0); /* OTG_CAP */
+ au_sync();
+ au_writel(sleep_usb[1], 0xb4020020 + 4); /* OTG_MUX */
+ au_sync();
+#endif
/* Restore the static memory controller configuration. */
au_writel(sleep_static_memctlr[0][0], MEM_STCFG0);
@@ -184,282 +201,17 @@ static void restore_core_regs(void)
}
restore_au1xxx_intctl();
- wakeup_counter0_adjust();
-}
-
-unsigned long suspend_mode;
-void wakeup_from_suspend(void)
-{
- suspend_mode = 0;
+#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
+ au1xxx_dbdma_resume();
+#endif
}
-int au_sleep(void)
+void au_sleep(void)
{
- unsigned long wakeup, flags;
- extern void save_and_sleep(void);
-
- spin_lock_irqsave(&pm_lock, flags);
-
save_core_regs();
-
- flush_cache_all();
-
- /**
- ** The code below is all system dependent and we should probably
- ** have a function call out of here to set this up. You need
- ** to configure the GPIO or timer interrupts that will bring
- ** you out of sleep.
- ** For testing, the TOY counter wakeup is useful.
- **/
-#if 0
- au_writel(au_readl(SYS_PINSTATERD) & ~(1 << 11), SYS_PINSTATERD);
-
- /* GPIO 6 can cause a wake up event */
- wakeup = au_readl(SYS_WAKEMSK);
- wakeup &= ~(1 << 8); /* turn off match20 wakeup */
- wakeup |= 1 << 6; /* turn on GPIO 6 wakeup */
-#else
- /* For testing, allow match20 to wake us up. */
-#ifdef SLEEP_TEST_TIMEOUT
- wakeup_counter0_set(sleep_ticks);
-#endif
- wakeup = 1 << 8; /* turn on match20 wakeup */
- wakeup = 0;
-#endif
- au_writel(1, SYS_WAKESRC); /* clear cause */
- au_sync();
- au_writel(wakeup, SYS_WAKEMSK);
- au_sync();
-
- save_and_sleep();
-
- /*
- * After a wakeup, the cpu vectors back to 0x1fc00000, so
- * it's up to the boot code to get us back here.
- */
+ au1xxx_save_and_sleep();
restore_core_regs();
- spin_unlock_irqrestore(&pm_lock, flags);
- return 0;
-}
-
-static int pm_do_sleep(ctl_table *ctl, int write, struct file *file,
- void __user *buffer, size_t *len, loff_t *ppos)
-{
-#ifdef SLEEP_TEST_TIMEOUT
-#define TMPBUFLEN2 16
- char buf[TMPBUFLEN2], *p;
-#endif
-
- if (!write)
- *len = 0;
- else {
-#ifdef SLEEP_TEST_TIMEOUT
- if (*len > TMPBUFLEN2 - 1)
- return -EFAULT;
- if (copy_from_user(buf, buffer, *len))
- return -EFAULT;
- buf[*len] = 0;
- p = buf;
- sleep_ticks = simple_strtoul(p, &p, 0);
-#endif
-
- au_sleep();
- }
- return 0;
-}
-
-static int pm_do_freq(ctl_table *ctl, int write, struct file *file,
- void __user *buffer, size_t *len, loff_t *ppos)
-{
- int retval = 0, i;
- unsigned long val, pll;
-#define TMPBUFLEN 64
-#define MAX_CPU_FREQ 396
- char buf[TMPBUFLEN], *p;
- unsigned long flags, intc0_mask, intc1_mask;
- unsigned long old_baud_base, old_cpu_freq, old_clk, old_refresh;
- unsigned long new_baud_base, new_cpu_freq, new_clk, new_refresh;
- unsigned long baud_rate;
-
- spin_lock_irqsave(&pm_lock, flags);
- if (!write)
- *len = 0;
- else {
- /* Parse the new frequency */
- if (*len > TMPBUFLEN - 1) {
- spin_unlock_irqrestore(&pm_lock, flags);
- return -EFAULT;
- }
- if (copy_from_user(buf, buffer, *len)) {
- spin_unlock_irqrestore(&pm_lock, flags);
- return -EFAULT;
- }
- buf[*len] = 0;
- p = buf;
- val = simple_strtoul(p, &p, 0);
- if (val > MAX_CPU_FREQ) {
- spin_unlock_irqrestore(&pm_lock, flags);
- return -EFAULT;
- }
-
- pll = val / 12;
- if ((pll > 33) || (pll < 7)) { /* 396 MHz max, 84 MHz min */
- /* Revisit this for higher speed CPUs */
- spin_unlock_irqrestore(&pm_lock, flags);
- return -EFAULT;
- }
-
- old_baud_base = get_au1x00_uart_baud_base();
- old_cpu_freq = get_au1x00_speed();
-
- new_cpu_freq = pll * 12 * 1000000;
- new_baud_base = (new_cpu_freq / (2 * ((int)(au_readl(SYS_POWERCTRL)
- & 0x03) + 2) * 16));
- set_au1x00_speed(new_cpu_freq);
- set_au1x00_uart_baud_base(new_baud_base);
-
- old_refresh = au_readl(MEM_SDREFCFG) & 0x1ffffff;
- new_refresh = ((old_refresh * new_cpu_freq) / old_cpu_freq) |
- (au_readl(MEM_SDREFCFG) & ~0x1ffffff);
-
- au_writel(pll, SYS_CPUPLL);
- au_sync_delay(1);
- au_writel(new_refresh, MEM_SDREFCFG);
- au_sync_delay(1);
-
- for (i = 0; i < 4; i++)
- if (au_readl(UART_BASE + UART_MOD_CNTRL +
- i * 0x00100000) == 3) {
- old_clk = au_readl(UART_BASE + UART_CLK +
- i * 0x00100000);
- baud_rate = old_baud_base / old_clk;
- /*
- * We won't get an exact baud rate and the error
- * could be significant enough that our new
- * calculation will result in a clock that will
- * give us a baud rate that's too far off from
- * what we really want.
- */
- if (baud_rate > 100000)
- baud_rate = 115200;
- else if (baud_rate > 50000)
- baud_rate = 57600;
- else if (baud_rate > 30000)
- baud_rate = 38400;
- else if (baud_rate > 17000)
- baud_rate = 19200;
- else
- baud_rate = 9600;
- new_clk = new_baud_base / baud_rate;
- au_writel(new_clk, UART_BASE + UART_CLK +
- i * 0x00100000);
- au_sync_delay(10);
- }
- }
-
- /*
- * We don't want _any_ interrupts other than 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);
- au1000_calibrate_delay();
- restore_local_and_enable(0, intc0_mask);
- restore_local_and_enable(1, intc1_mask);
-
- return retval;
}
-
-static struct ctl_table pm_table[] = {
- {
- .ctl_name = CTL_UNNUMBERED,
- .procname = "sleep",
- .data = NULL,
- .maxlen = 0,
- .mode = 0600,
- .proc_handler = &pm_do_sleep
- },
- {
- .ctl_name = CTL_UNNUMBERED,
- .procname = "freq",
- .data = NULL,
- .maxlen = 0,
- .mode = 0600,
- .proc_handler = &pm_do_freq
- },
- {}
-};
-
-static struct ctl_table pm_dir_table[] = {
- {
- .ctl_name = CTL_UNNUMBERED,
- .procname = "pm",
- .mode = 0555,
- .child = pm_table
- },
- {}
-};
-
-/*
- * Initialize power interface
- */
-static int __init pm_init(void)
-{
- register_sysctl_table(pm_dir_table);
- return 0;
-}
-
-__initcall(pm_init);
-
-/*
- * This is right out of init/main.c
- */
-
-/*
- * This is the number of bits of precision for the loops_per_jiffy.
- * Each bit takes on average 1.5/HZ seconds. This (like the original)
- * is a little better than 1%.
- */
-#define LPS_PREC 8
-
-static void au1000_calibrate_delay(void)
-{
- unsigned long ticks, loopbit;
- int lps_precision = LPS_PREC;
-
- loops_per_jiffy = 1 << 12;
-
- while (loops_per_jiffy <<= 1) {
- /* Wait for "start of" clock tick */
- ticks = jiffies;
- while (ticks == jiffies)
- /* nothing */ ;
- /* Go ... */
- ticks = jiffies;
- __delay(loops_per_jiffy);
- ticks = jiffies - ticks;
- if (ticks)
- break;
- }
-
- /*
- * Do a binary approximation to get loops_per_jiffy set to be equal
- * one clock (up to lps_precision bits)
- */
- loops_per_jiffy >>= 1;
- loopbit = loops_per_jiffy;
- while (lps_precision-- && (loopbit >>= 1)) {
- loops_per_jiffy |= loopbit;
- ticks = jiffies;
- while (ticks == jiffies);
- ticks = jiffies;
- __delay(loops_per_jiffy);
- if (jiffies != ticks) /* longer than 1 tick */
- loops_per_jiffy &= ~loopbit;
- }
-}
#endif /* CONFIG_PM */
diff --git a/arch/mips/alchemy/common/reset.c b/arch/mips/alchemy/common/reset.c
index d555429..0191c93 100644
--- a/arch/mips/alchemy/common/reset.c
+++ b/arch/mips/alchemy/common/reset.c
@@ -31,8 +31,6 @@
#include <asm/mach-au1x00/au1000.h>
-extern int au_sleep(void);
-
void au1000_restart(char *command)
{
/* Set all integrated peripherals to disabled states */
diff --git a/arch/mips/alchemy/common/setup.c b/arch/mips/alchemy/common/setup.c
index 1ac6b06..3f036b3 100644
--- a/arch/mips/alchemy/common/setup.c
+++ b/arch/mips/alchemy/common/setup.c
@@ -35,7 +35,6 @@
#include <asm/time.h>
#include <au1000.h>
-#include <prom.h>
extern void __init board_setup(void);
extern void au1000_restart(char *);
@@ -45,80 +44,34 @@ extern void set_cpuspec(void);
void __init plat_mem_setup(void)
{
- struct cpu_spec *sp;
- char *argptr;
- unsigned long prid, cpufreq, bclk;
+ unsigned long est_freq;
- set_cpuspec();
- sp = cur_cpu_spec[0];
+ /* determine core clock */
+ est_freq = au1xxx_calc_clock();
+ est_freq += 5000; /* round */
+ est_freq -= est_freq % 10000;
+ printk(KERN_INFO "(PRId %08x) @ %lu.%02lu MHz\n", read_c0_prid(),
+ est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000);
- board_setup(); /* board specific setup */
-
- prid = read_c0_prid();
- if (sp->cpu_pll_wo)
-#ifdef CONFIG_SOC_AU1000_FREQUENCY
- cpufreq = CONFIG_SOC_AU1000_FREQUENCY / 1000000;
-#else
- cpufreq = 396;
-#endif
- else
- cpufreq = (au_readl(SYS_CPUPLL) & 0x3F) * 12;
- printk(KERN_INFO "(PRID %08lx) @ %ld MHz\n", prid, cpufreq);
+ _machine_restart = au1000_restart;
+ _machine_halt = au1000_halt;
+ pm_power_off = au1000_power_off;
- if (sp->cpu_bclk) {
- /* Enable BCLK switching */
- bclk = au_readl(SYS_POWERCTRL);
- au_writel(bclk | 0x60, SYS_POWERCTRL);
- printk(KERN_INFO "BCLK switching enabled!\n");
- }
+ board_setup(); /* board specific setup */
- if (sp->cpu_od)
+ if (au1xxx_cpu_needs_config_od())
/* Various early Au1xx0 errata corrected by this */
set_c0_config(1 << 19); /* Set Config[OD] */
else
/* Clear to obtain best system bus performance */
clear_c0_config(1 << 19); /* Clear Config[OD] */
- argptr = prom_getcmdline();
-
-#ifdef CONFIG_SERIAL_8250_CONSOLE
- argptr = strstr(argptr, "console=");
- if (argptr == NULL) {
- argptr = prom_getcmdline();
- strcat(argptr, " console=ttyS0,115200");
- }
-#endif
-
-#ifdef CONFIG_FB_AU1100
- argptr = strstr(argptr, "video=");
- if (argptr == NULL) {
- argptr = prom_getcmdline();
- /* default panel */
- /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
- }
-#endif
-
-#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
- /* au1000 does not support vra, au1500 and au1100 do */
- strcat(argptr, " au1000_audio=vra");
- argptr = prom_getcmdline();
-#endif
- _machine_restart = au1000_restart;
- _machine_halt = au1000_halt;
- pm_power_off = au1000_power_off;
-
/* IO/MEM resources. */
set_io_port_base(0);
ioport_resource.start = IOPORT_RESOURCE_START;
ioport_resource.end = IOPORT_RESOURCE_END;
iomem_resource.start = IOMEM_RESOURCE_START;
iomem_resource.end = IOMEM_RESOURCE_END;
-
- while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_E0S);
- au_writel(SYS_CNTRL_E0 | SYS_CNTRL_EN0, SYS_COUNTER_CNTRL);
- au_sync();
- while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T0S);
- au_writel(0, SYS_TOYTRIM);
}
#if defined(CONFIG_64BIT_PHYS_ADDR)
diff --git a/arch/mips/alchemy/common/sleeper.S b/arch/mips/alchemy/common/sleeper.S
index 3006e27..4f4b167 100644
--- a/arch/mips/alchemy/common/sleeper.S
+++ b/arch/mips/alchemy/common/sleeper.S
@@ -15,16 +15,17 @@
#include <asm/regdef.h>
#include <asm/stackframe.h>
+ .extern __flush_cache_all
+
.text
- .set macro
- .set noat
+ .set noreorder
+ .set noat
.align 5
/* Save all of the processor general registers and go to sleep.
* A wakeup condition will get us back here to restore the registers.
*/
-LEAF(save_and_sleep)
-
+LEAF(au1xxx_save_and_sleep)
subu sp, PT_SIZE
sw $1, PT_R1(sp)
sw $2, PT_R2(sp)
@@ -33,14 +34,6 @@ LEAF(save_and_sleep)
sw $5, PT_R5(sp)
sw $6, PT_R6(sp)
sw $7, PT_R7(sp)
- sw $8, PT_R8(sp)
- sw $9, PT_R9(sp)
- sw $10, PT_R10(sp)
- sw $11, PT_R11(sp)
- sw $12, PT_R12(sp)
- sw $13, PT_R13(sp)
- sw $14, PT_R14(sp)
- sw $15, PT_R15(sp)
sw $16, PT_R16(sp)
sw $17, PT_R17(sp)
sw $18, PT_R18(sp)
@@ -49,12 +42,9 @@ LEAF(save_and_sleep)
sw $21, PT_R21(sp)
sw $22, PT_R22(sp)
sw $23, PT_R23(sp)
- sw $24, PT_R24(sp)
- sw $25, PT_R25(sp)
sw $26, PT_R26(sp)
sw $27, PT_R27(sp)
sw $28, PT_R28(sp)
- sw $29, PT_R29(sp)
sw $30, PT_R30(sp)
sw $31, PT_R31(sp)
mfc0 k0, CP0_STATUS
@@ -66,20 +56,26 @@ LEAF(save_and_sleep)
mfc0 k0, CP0_CONFIG
sw k0, 0x14(sp)
+ /* flush caches to make sure context is in memory */
+ la t1, __flush_cache_all
+ lw t0, 0(t1)
+ jalr t0
+ nop
+
/* Now set up the scratch registers so the boot rom will
* return to this point upon wakeup.
+ * sys_scratch0 : SP
+ * sys_scratch1 : RA
*/
- la k0, 1f
- lui k1, 0xb190
- ori k1, 0x18
- sw sp, 0(k1)
- ori k1, 0x1c
- sw k0, 0(k1)
+ lui t3, 0xb190 /* sys_xxx */
+ sw sp, 0x0018(t3)
+ la k0, 3f /* resume path */
+ sw k0, 0x001c(t3)
-/* Put SDRAM into self refresh. Preload instructions into cache,
- * issue a precharge, then auto refresh, then sleep commands to it.
- */
- la t0, sdsleep
+ /* Put SDRAM into self refresh: Preload instructions into cache,
+ * issue a precharge, auto/self refresh, then sleep commands to it.
+ */
+ la t0, 1f
.set mips3
cache 0x14, 0(t0)
cache 0x14, 32(t0)
@@ -87,24 +83,57 @@ LEAF(save_and_sleep)
cache 0x14, 96(t0)
.set mips0
-sdsleep:
- lui k0, 0xb400
- sw zero, 0x001c(k0) /* Precharge */
- sw zero, 0x0020(k0) /* Auto refresh */
- sw zero, 0x0030(k0) /* SDRAM sleep */
+1: lui a0, 0xb400 /* mem_xxx */
+#if defined(CONFIG_SOC_AU1000) || defined(CONFIG_SOC_AU1100) || \
+ defined(CONFIG_SOC_AU1500)
+ sw zero, 0x001c(a0) /* Precharge */
+ sync
+ sw zero, 0x0020(a0) /* Auto Refresh */
+ sync
+ sw zero, 0x0030(a0) /* Sleep */
+ sync
+#endif
+
+#if defined(CONFIG_SOC_AU1550) || defined(CONFIG_SOC_AU1200)
+ sw zero, 0x08c0(a0) /* Precharge */
sync
+ sw zero, 0x08d0(a0) /* Self Refresh */
+ sync
+
+ /* wait for sdram to enter self-refresh mode */
+ lui t0, 0x0100
+2: lw t1, 0x0850(a0) /* mem_sdstat */
+ and t2, t1, t0
+ beq t2, zero, 2b
+ nop
- lui k1, 0xb190
- sw zero, 0x0078(k1) /* get ready to sleep */
+ /* disable SDRAM clocks */
+ lui t0, 0xcfff
+ ori t0, t0, 0xffff
+ lw t1, 0x0840(a0) /* mem_sdconfiga */
+ and t1, t0, t1 /* clear CE[1:0] */
+ sw t1, 0x0840(a0) /* mem_sdconfiga */
sync
- sw zero, 0x007c(k1) /* Put processor to sleep */
+#endif
+
+ /* put power supply and processor to sleep */
+ sw zero, 0x0078(t3) /* sys_slppwr */
+ sync
+ sw zero, 0x007c(t3) /* sys_sleep */
sync
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
+ nop
/* This is where we return upon wakeup.
* Reload all of the registers and return.
*/
-1: nop
- lw k0, 0x20(sp)
+3: lw k0, 0x20(sp)
mtc0 k0, CP0_STATUS
lw k0, 0x1c(sp)
mtc0 k0, CP0_CONTEXT
@@ -113,10 +142,11 @@ sdsleep:
lw k0, 0x14(sp)
mtc0 k0, CP0_CONFIG
- /* We need to catch the ealry Alchemy SOCs with
+ /* We need to catch the early Alchemy SOCs with
* the write-only Config[OD] bit and set it back to one...
*/
jal au1x00_fixup_config_od
+ nop
lw $1, PT_R1(sp)
lw $2, PT_R2(sp)
lw $3, PT_R3(sp)
@@ -124,14 +154,6 @@ sdsleep:
lw $5, PT_R5(sp)
lw $6, PT_R6(sp)
lw $7, PT_R7(sp)
- lw $8, PT_R8(sp)
- lw $9, PT_R9(sp)
- lw $10, PT_R10(sp)
- lw $11, PT_R11(sp)
- lw $12, PT_R12(sp)
- lw $13, PT_R13(sp)
- lw $14, PT_R14(sp)
- lw $15, PT_R15(sp)
lw $16, PT_R16(sp)
lw $17, PT_R17(sp)
lw $18, PT_R18(sp)
@@ -140,15 +162,11 @@ sdsleep:
lw $21, PT_R21(sp)
lw $22, PT_R22(sp)
lw $23, PT_R23(sp)
- lw $24, PT_R24(sp)
- lw $25, PT_R25(sp)
lw $26, PT_R26(sp)
lw $27, PT_R27(sp)
lw $28, PT_R28(sp)
- lw $29, PT_R29(sp)
lw $30, PT_R30(sp)
lw $31, PT_R31(sp)
- addiu sp, PT_SIZE
-
jr ra
-END(save_and_sleep)
+ addiu sp, PT_SIZE
+END(au1xxx_save_and_sleep)
diff --git a/arch/mips/alchemy/common/time.c b/arch/mips/alchemy/common/time.c
index 563d939..3288014 100644
--- a/arch/mips/alchemy/common/time.c
+++ b/arch/mips/alchemy/common/time.c
@@ -1,5 +1,7 @@
/*
+ * Copyright (C) 2008 Manuel Lauss <mano@roarinelk.homelinux.net>
*
+ * Previous incarnations were:
* Copyright (C) 2001, 2006, 2008 MontaVista Software, <source@mvista.com>
* Copied and modified Carsten Langgaard's time.c
*
@@ -23,244 +25,141 @@
*
* ########################################################################
*
- * Setting up the clock on the MIPS boards.
- *
- * We provide the clock interrupt processing and the timer offset compute
- * functions. If CONFIG_PM is selected, we also ensure the 32KHz timer is
- * available. -- Dan
+ * Clocksource/event using the 32.768kHz-clocked Counter1 ('RTC' in the
+ * databooks). Firmware/Board init code must enable the counters in the
+ * counter control register, otherwise the CP0 counter clocksource/event
+ * will be installed instead (and use of 'wait' instruction is prohibited).
*/
-#include <linux/types.h>
-#include <linux/init.h>
+#include <linux/clockchips.h>
+#include <linux/clocksource.h>
+#include <linux/interrupt.h>
#include <linux/spinlock.h>
-#include <asm/mipsregs.h>
#include <asm/time.h>
#include <asm/mach-au1x00/au1000.h>
-static int no_au1xxx_32khz;
-extern int allow_au1k_wait; /* default off for CP0 Counter */
-
-#ifdef CONFIG_PM
-#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... */
-static unsigned long last_pc0, last_match20;
-#endif
+/* 32kHz clock enabled and detected */
+#define CNTR_OK (SYS_CNTRL_E0 | SYS_CNTRL_32S)
-static DEFINE_SPINLOCK(time_lock);
-
-unsigned long wtimer;
+extern int allow_au1k_wait; /* default off for CP0 Counter */
-#ifdef CONFIG_PM
-static irqreturn_t counter0_irq(int irq, void *dev_id)
+static cycle_t au1x_counter1_read(void)
{
- unsigned long pc0;
- int time_elapsed;
- static int jiffie_drift;
-
- if (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20) {
- /* should never happen! */
- printk(KERN_WARNING "counter 0 w status error\n");
- return IRQ_NONE;
- }
-
- pc0 = au_readl(SYS_TOYREAD);
- if (pc0 < last_match20)
- /* counter overflowed */
- time_elapsed = (0xffffffff - last_match20) + pc0;
- else
- time_elapsed = pc0 - last_match20;
-
- while (time_elapsed > 0) {
- do_timer(1);
-#ifndef CONFIG_SMP
- update_process_times(user_mode(get_irq_regs()));
-#endif
- time_elapsed -= MATCH20_INC;
- last_match20 += MATCH20_INC;
- jiffie_drift++;
- }
-
- last_pc0 = pc0;
- au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
- au_sync();
-
- /*
- * Our counter ticks at 10.009765625 ms/tick, we we're running
- * almost 10 uS too slow per tick.
- */
-
- if (jiffie_drift >= 999) {
- jiffie_drift -= 999;
- do_timer(1); /* increment jiffies by one */
-#ifndef CONFIG_SMP
- update_process_times(user_mode(get_irq_regs()));
-#endif
- }
-
- return IRQ_HANDLED;
+ return au_readl(SYS_RTCREAD);
}
-struct irqaction counter0_action = {
- .handler = counter0_irq,
- .flags = IRQF_DISABLED,
- .name = "alchemy-toy",
- .dev_id = NULL,
+static struct clocksource au1x_counter1_clocksource = {
+ .name = "alchemy-counter1",
+ .read = au1x_counter1_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+ .rating = 100,
};
-/* When we wakeup from sleep, we have to "catch up" on all of the
- * timer ticks we have missed.
- */
-void wakeup_counter0_adjust(void)
+static int au1x_rtcmatch2_set_next_event(unsigned long delta,
+ struct clock_event_device *cd)
{
- unsigned long pc0;
- int time_elapsed;
-
- pc0 = au_readl(SYS_TOYREAD);
- if (pc0 < last_match20)
- /* counter overflowed */
- time_elapsed = (0xffffffff - last_match20) + pc0;
- else
- time_elapsed = pc0 - last_match20;
-
- while (time_elapsed > 0) {
- time_elapsed -= MATCH20_INC;
- last_match20 += MATCH20_INC;
- }
-
- last_pc0 = pc0;
- au_writel(last_match20 + MATCH20_INC, SYS_TOYMATCH2);
+ delta += au_readl(SYS_RTCREAD);
+ /* wait for register access */
+ while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M21)
+ ;
+ au_writel(delta, SYS_RTCMATCH2);
au_sync();
+ return 0;
}
-/* This is just for debugging to set the timer for a sleep delay. */
-void wakeup_counter0_set(int ticks)
+static void au1x_rtcmatch2_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *cd)
{
- unsigned long pc0;
-
- pc0 = au_readl(SYS_TOYREAD);
- last_pc0 = pc0;
- au_writel(last_match20 + (MATCH20_INC * ticks), SYS_TOYMATCH2);
- au_sync();
}
-#endif
-/*
- * I haven't found anyone that doesn't use a 12 MHz source clock,
- * but just in case.....
- */
-#define AU1000_SRC_CLK 12000000
-
-/*
- * We read the real processor speed from the PLL. This is important
- * because it is more accurate than computing it from the 32 KHz
- * counter, if it exists. If we don't have an accurate processor
- * speed, all of the peripherals that derive their clocks based on
- * this advertised speed will introduce error and sometimes not work
- * properly. This function is futher convoluted to still allow configurations
- * to do that in case they have really, really old silicon with a
- * write-only PLL register, that we need the 32 KHz when power management
- * "wait" is enabled, and we need to detect if the 32 KHz isn't present
- * but requested......got it? :-) -- Dan
- */
-unsigned long calc_clock(void)
+static irqreturn_t au1x_rtcmatch2_irq(int irq, void *dev_id)
{
- unsigned long cpu_speed;
- unsigned long flags;
- unsigned long counter;
-
- spin_lock_irqsave(&time_lock, flags);
-
- /* Power management cares if we don't have a 32 KHz counter. */
- no_au1xxx_32khz = 0;
- counter = au_readl(SYS_COUNTER_CNTRL);
- if (counter & SYS_CNTRL_E0) {
- int trim_divide = 16;
-
- au_writel(counter | SYS_CNTRL_EN1, SYS_COUNTER_CNTRL);
-
- while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
- /* RTC now ticks at 32.768/16 kHz */
- au_writel(trim_divide - 1, SYS_RTCTRIM);
- while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S);
+ struct clock_event_device *cd = dev_id;
+ cd->event_handler(cd);
+ return IRQ_HANDLED;
+}
- while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
- au_writel(0, SYS_TOYWRITE);
- while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S);
- } else
- no_au1xxx_32khz = 1;
+static struct clock_event_device au1x_rtcmatch2_clockdev = {
+ .name = "rtcmatch2",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .rating = 100,
+ .irq = AU1000_RTC_MATCH2_INT,
+ .set_next_event = au1x_rtcmatch2_set_next_event,
+ .set_mode = au1x_rtcmatch2_set_mode,
+ .cpumask = CPU_MASK_ALL,
+};
- /*
- * On early Au1000, sys_cpupll was write-only. Since these
- * silicon versions of Au1000 are not sold by AMD, we don't bend
- * over backwards trying to determine the frequency.
- */
- if (cur_cpu_spec[0]->cpu_pll_wo)
-#ifdef CONFIG_SOC_AU1000_FREQUENCY
- cpu_speed = CONFIG_SOC_AU1000_FREQUENCY;
-#else
- cpu_speed = 396000000;
-#endif
- else
- cpu_speed = (au_readl(SYS_CPUPLL) & 0x0000003f) * AU1000_SRC_CLK;
- /* On Alchemy CPU:counter ratio is 1:1 */
- mips_hpt_frequency = cpu_speed;
- /* Equation: Baudrate = CPU / (SD * 2 * CLKDIV * 16) */
- set_au1x00_uart_baud_base(cpu_speed / (2 * ((int)(au_readl(SYS_POWERCTRL)
- & 0x03) + 2) * 16));
- spin_unlock_irqrestore(&time_lock, flags);
- return cpu_speed;
-}
+static struct irqaction au1x_rtcmatch2_irqaction = {
+ .handler = au1x_rtcmatch2_irq,
+ .flags = IRQF_DISABLED | IRQF_TIMER,
+ .name = "timer",
+ .dev_id = &au1x_rtcmatch2_clockdev,
+};
void __init plat_time_init(void)
{
- unsigned int est_freq = calc_clock();
-
- est_freq += 5000; /* round */
- est_freq -= est_freq%10000;
- printk(KERN_INFO "CPU frequency %u.%02u MHz\n",
- est_freq / 1000000, ((est_freq % 1000000) * 100) / 1000000);
- set_au1x00_speed(est_freq);
- set_au1x00_lcd_clock(); /* program the LCD clock */
+ struct clock_event_device *cd = &au1x_rtcmatch2_clockdev;
+ unsigned long t;
+
+ /* Check if firmware (YAMON, ...) has enabled 32kHz and clock
+ * has been detected. If so install the rtcmatch2 clocksource,
+ * otherwise don't bother. Note that both bits being set is by
+ * no means a definite guarantee that the counters actually work
+ * (the 32S bit seems to be stuck set to 1 once a single clock-
+ * edge is detected, hence the timeouts).
+ */
+ if (CNTR_OK != (au_readl(SYS_COUNTER_CNTRL) & CNTR_OK))
+ goto cntr_err;
-#ifdef CONFIG_PM
/*
- * setup counter 0, since it keeps ticking after a
- * 'wait' instruction has been executed. The CP0 timer and
- * counter 1 do NOT continue running after 'wait'
- *
- * It's too early to call request_irq() here, so we handle
- * counter 0 interrupt as a special irq and it doesn't show
- * up under /proc/interrupts.
- *
- * Check to ensure we really have a 32 KHz oscillator before
- * we do this.
+ * setup counter 1 (RTC) to tick at full speed
*/
- if (no_au1xxx_32khz)
- printk(KERN_WARNING "WARNING: no 32KHz clock found.\n");
- else {
- while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
- au_writel(0, SYS_TOYWRITE);
- while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C0S);
-
- au_writel(au_readl(SYS_WAKEMSK) | (1 << 8), SYS_WAKEMSK);
- au_writel(~0, SYS_WAKESRC);
- au_sync();
- while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20);
+ t = 0xffffff;
+ while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_T1S) && t--)
+ asm volatile ("nop");
+ if (!t)
+ goto cntr_err;
- /* 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);
- setup_irq(AU1000_TOY_MATCH2_INT, &counter0_action);
+ au_writel(0, SYS_RTCTRIM); /* 32.768 kHz */
+ au_sync();
- /* We can use the real 'wait' instruction. */
- allow_au1k_wait = 1;
- }
+ t = 0xffffff;
+ while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && t--)
+ asm volatile ("nop");
+ if (!t)
+ goto cntr_err;
+ au_writel(0, SYS_RTCWRITE);
+ au_sync();
-#endif
+ t = 0xffffff;
+ while ((au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_C1S) && t--)
+ asm volatile ("nop");
+ if (!t)
+ goto cntr_err;
+
+ /* register counter1 clocksource and event device */
+ clocksource_set_clock(&au1x_counter1_clocksource, 32768);
+ clocksource_register(&au1x_counter1_clocksource);
+
+ cd->shift = 32;
+ cd->mult = div_sc(32768, NSEC_PER_SEC, cd->shift);
+ cd->max_delta_ns = clockevent_delta2ns(0xffffffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(8, cd); /* ~0.25ms */
+ clockevents_register_device(cd);
+ setup_irq(AU1000_RTC_MATCH2_INT, &au1x_rtcmatch2_irqaction);
+
+ printk(KERN_INFO "Alchemy clocksource installed\n");
+
+ /* can now use 'wait' */
+ allow_au1k_wait = 1;
+ return;
+
+cntr_err:
+ /* counters unusable, use C0 counter */
+ r4k_clockevent_init();
+ init_r4k_clocksource();
+ allow_au1k_wait = 0;
}
diff --git a/arch/mips/alchemy/db1x00/init.c b/arch/mips/alchemy/db1x00/init.c
deleted file mode 100644
index 8474135..0000000
--- a/arch/mips/alchemy/db1x00/init.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- * PB1000 board setup
- *
- * Copyright 2001, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <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/kernel.h>
-
-#include <asm/bootinfo.h>
-
-#include <prom.h>
-
-const char *get_system_type(void)
-{
-#ifdef CONFIG_MIPS_BOSPORUS
- return "Alchemy Bosporus Gateway Reference";
-#else
- return "Alchemy Db1x00";
-#endif
-}
-
-void __init prom_init(void)
-{
- unsigned char *memsize_str;
- unsigned long memsize;
-
- prom_argc = fw_arg0;
- prom_argv = (char **)fw_arg1;
- prom_envp = (char **)fw_arg2;
-
- prom_init_cmdline();
-
- memsize_str = prom_getenv("memsize");
- if (!memsize_str)
- memsize = 0x04000000;
- else
- strict_strtol(memsize_str, 0, &memsize);
- add_memory_region(0, memsize, BOOT_MEM_RAM);
-}
diff --git a/arch/mips/alchemy/devboards/Makefile b/arch/mips/alchemy/devboards/Makefile
new file mode 100644
index 0000000..730f9f2
--- /dev/null
+++ b/arch/mips/alchemy/devboards/Makefile
@@ -0,0 +1,18 @@
+#
+# Alchemy Develboards
+#
+
+obj-y += prom.o
+obj-$(CONFIG_PM) += pm.o
+obj-$(CONFIG_MIPS_PB1000) += pb1000/
+obj-$(CONFIG_MIPS_PB1100) += pb1100/
+obj-$(CONFIG_MIPS_PB1200) += pb1200/
+obj-$(CONFIG_MIPS_PB1500) += pb1500/
+obj-$(CONFIG_MIPS_PB1550) += pb1550/
+obj-$(CONFIG_MIPS_DB1000) += db1x00/
+obj-$(CONFIG_MIPS_DB1100) += db1x00/
+obj-$(CONFIG_MIPS_DB1200) += pb1200/
+obj-$(CONFIG_MIPS_DB1500) += db1x00/
+obj-$(CONFIG_MIPS_DB1550) += db1x00/
+obj-$(CONFIG_MIPS_BOSPORUS) += db1x00/
+obj-$(CONFIG_MIPS_MIRAGE) += db1x00/
diff --git a/arch/mips/alchemy/db1x00/Makefile b/arch/mips/alchemy/devboards/db1x00/Makefile
index 274db3b..432241a 100644
--- a/arch/mips/alchemy/db1x00/Makefile
+++ b/arch/mips/alchemy/devboards/db1x00/Makefile
@@ -5,4 +5,4 @@
# Makefile for the Alchemy Semiconductor DBAu1xx0 boards.
#
-lib-y := init.o board_setup.o irqmap.o
+obj-y := board_setup.o irqmap.o
diff --git a/arch/mips/alchemy/db1x00/board_setup.c b/arch/mips/alchemy/devboards/db1x00/board_setup.c
index 9e5ccbb..a75ffbf 100644
--- a/arch/mips/alchemy/db1x00/board_setup.c
+++ b/arch/mips/alchemy/devboards/db1x00/board_setup.c
@@ -32,8 +32,20 @@
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/db1x00.h>
+#include <prom.h>
+
+
static BCSR * const bcsr = (BCSR *)BCSR_KSEG1_ADDR;
+const char *get_system_type(void)
+{
+#ifdef CONFIG_MIPS_BOSPORUS
+ return "Alchemy Bosporus Gateway Reference";
+#else
+ return "Alchemy Db1x00";
+#endif
+}
+
void board_reset(void)
{
/* Hit BCSR.SW_RESET[RESET] */
@@ -43,6 +55,31 @@ void board_reset(void)
void __init board_setup(void)
{
u32 pin_func = 0;
+ char *argptr;
+
+ argptr = prom_getcmdline();
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ argptr = strstr(argptr, "console=");
+ if (argptr == NULL) {
+ argptr = prom_getcmdline();
+ strcat(argptr, " console=ttyS0,115200");
+ }
+#endif
+
+#ifdef CONFIG_FB_AU1100
+ argptr = strstr(argptr, "video=");
+ if (argptr == NULL) {
+ argptr = prom_getcmdline();
+ /* default panel */
+ /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
+ }
+#endif
+
+#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
+ /* au1000 does not support vra, au1500 and au1100 do */
+ strcat(argptr, " au1000_audio=vra");
+ argptr = prom_getcmdline();
+#endif
/* Not valid for Au1550 */
#if defined(CONFIG_IRDA) && \
diff --git a/arch/mips/alchemy/db1x00/irqmap.c b/arch/mips/alchemy/devboards/db1x00/irqmap.c
index 94c090e..0b09025 100644
--- a/arch/mips/alchemy/db1x00/irqmap.c
+++ b/arch/mips/alchemy/devboards/db1x00/irqmap.c
@@ -27,6 +27,7 @@
*/
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <asm/mach-au1x00/au1000.h>
@@ -66,21 +67,24 @@ struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
#ifndef CONFIG_MIPS_MIRAGE
#ifdef CONFIG_MIPS_DB1550
- { AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 IRQ# */
- { AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 IRQ# */
+ { AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 IRQ# */
+ { AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 IRQ# */
#else
- { AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 Fully_Interted# */
- { AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 STSCHG# */
- { AU1000_GPIO_2, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 0 IRQ# */
+ { AU1000_GPIO_0, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 Fully_Interted# */
+ { AU1000_GPIO_1, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 STSCHG# */
+ { AU1000_GPIO_2, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 0 IRQ# */
- { AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 Fully_Interted# */
- { AU1000_GPIO_4, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 STSCHG# */
- { AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card 1 IRQ# */
+ { AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 Fully_Interted# */
+ { AU1000_GPIO_4, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 STSCHG# */
+ { AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card 1 IRQ# */
#endif
#else
- { AU1000_GPIO_7, INTC_INT_RISE_EDGE, 0 }, /* touchscreen pen down */
+ { AU1000_GPIO_7, IRQF_TRIGGER_RISING, 0 }, /* touchscreen pen down */
#endif
};
-int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
+void __init board_init_irq(void)
+{
+ au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
+}
diff --git a/arch/mips/alchemy/pb1000/Makefile b/arch/mips/alchemy/devboards/pb1000/Makefile
index 99bbec0..97c6615 100644
--- a/arch/mips/alchemy/pb1000/Makefile
+++ b/arch/mips/alchemy/devboards/pb1000/Makefile
@@ -5,4 +5,4 @@
# Makefile for the Alchemy Semiconductor Pb1000 board.
#
-lib-y := init.o board_setup.o irqmap.o
+obj-y := board_setup.o
diff --git a/arch/mips/alchemy/pb1000/board_setup.c b/arch/mips/alchemy/devboards/pb1000/board_setup.c
index 25df167..aed2fde 100644
--- a/arch/mips/alchemy/pb1000/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1000/board_setup.c
@@ -23,22 +23,48 @@
* 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-#include <linux/init.h>
#include <linux/delay.h>
-
+#include <linux/init.h>
+#include <linux/interrupt.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1000.h>
+#include <prom.h>
+
+
+struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
+ { AU1000_GPIO_15, IRQF_TRIGGER_LOW, 0 },
+};
+
+
+const char *get_system_type(void)
+{
+ return "Alchemy Pb1000";
+}
void board_reset(void)
{
}
+void __init board_init_irq(void)
+{
+ au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
+}
+
void __init board_setup(void)
{
u32 pin_func, static_cfg0;
u32 sys_freqctrl, sys_clksrc;
u32 prid = read_c0_prid();
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ char *argptr = prom_getcmdline();
+ argptr = strstr(argptr, "console=");
+ if (argptr == NULL) {
+ argptr = prom_getcmdline();
+ strcat(argptr, " console=ttyS0,115200");
+ }
+#endif
+
/* Set AUX clock to 12 MHz * 8 = 96 MHz */
au_writel(8, SYS_AUXPLL);
au_writel(0, SYS_PINSTATERD);
diff --git a/arch/mips/alchemy/pb1100/Makefile b/arch/mips/alchemy/devboards/pb1100/Makefile
index 793e97c..c586dd7 100644
--- a/arch/mips/alchemy/pb1100/Makefile
+++ b/arch/mips/alchemy/devboards/pb1100/Makefile
@@ -5,4 +5,4 @@
# Makefile for the Alchemy Semiconductor Pb1100 board.
#
-lib-y := init.o board_setup.o irqmap.o
+obj-y := board_setup.o
diff --git a/arch/mips/alchemy/pb1100/board_setup.c b/arch/mips/alchemy/devboards/pb1100/board_setup.c
index c0bfd59..4df57fa 100644
--- a/arch/mips/alchemy/pb1100/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1100/board_setup.c
@@ -25,19 +25,66 @@
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/interrupt.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1100.h>
+#include <prom.h>
+
+
+struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
+ { AU1000_GPIO_9, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card Fully_Inserted# */
+ { AU1000_GPIO_10, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card STSCHG# */
+ { AU1000_GPIO_11, IRQF_TRIGGER_LOW, 0 }, /* PCMCIA Card IRQ# */
+ { AU1000_GPIO_13, IRQF_TRIGGER_LOW, 0 }, /* DC_IRQ# */
+};
+
+
+const char *get_system_type(void)
+{
+ return "Alchemy Pb1100";
+}
+
void board_reset(void)
{
/* Hit BCSR.RST_VDDI[SOFT_RESET] */
au_writel(0x00000000, PB1100_RST_VDDI);
}
+void __init board_init_irq(void)
+{
+ au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
+}
+
void __init board_setup(void)
{
volatile void __iomem *base = (volatile void __iomem *)0xac000000UL;
+ char *argptr;
+
+ argptr = prom_getcmdline();
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ argptr = strstr(argptr, "console=");
+ if (argptr == NULL) {
+ argptr = prom_getcmdline();
+ strcat(argptr, " console=ttyS0,115200");
+ }
+#endif
+
+#ifdef CONFIG_FB_AU1100
+ argptr = strstr(argptr, "video=");
+ if (argptr == NULL) {
+ argptr = prom_getcmdline();
+ /* default panel */
+ /*strcat(argptr, " video=au1100fb:panel:Sharp_320x240_16");*/
+ }
+#endif
+
+#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
+ /* au1000 does not support vra, au1500 and au1100 do */
+ strcat(argptr, " au1000_audio=vra");
+ argptr = prom_getcmdline();
+#endif
/* Set AUX clock to 12 MHz * 8 = 96 MHz */
au_writel(8, SYS_AUXPLL);
diff --git a/arch/mips/alchemy/pb1200/Makefile b/arch/mips/alchemy/devboards/pb1200/Makefile
index d678adf..c8c3a99 100644
--- a/arch/mips/alchemy/pb1200/Makefile
+++ b/arch/mips/alchemy/devboards/pb1200/Makefile
@@ -2,7 +2,6 @@
# Makefile for the Alchemy Semiconductor Pb1200/DBAu1200 boards.
#
-lib-y := init.o board_setup.o irqmap.o
-obj-y += platform.o
+obj-y := board_setup.o irqmap.o platform.o
EXTRA_CFLAGS += -Werror
diff --git a/arch/mips/alchemy/pb1200/board_setup.c b/arch/mips/alchemy/devboards/pb1200/board_setup.c
index 6cb2115..94e6b7e 100644
--- a/arch/mips/alchemy/pb1200/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1200/board_setup.c
@@ -30,8 +30,11 @@
#include <prom.h>
#include <au1xxx.h>
-extern void _board_init_irq(void);
-extern void (*board_init_irq)(void);
+
+const char *get_system_type(void)
+{
+ return "Alchemy Pb1200";
+}
void board_reset(void)
{
@@ -41,7 +44,19 @@ void board_reset(void)
void __init board_setup(void)
{
- char *argptr = NULL;
+ char *argptr;
+
+ argptr = prom_getcmdline();
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ argptr = strstr(argptr, "console=");
+ if (argptr == NULL) {
+ argptr = prom_getcmdline();
+ strcat(argptr, " console=ttyS0,115200");
+ }
+#endif
+#ifdef CONFIG_FB_AU1200
+ strcat(argptr, " video=au1200fb:panel:bs");
+#endif
#if 0
{
@@ -99,16 +114,6 @@ void __init board_setup(void)
}
#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
@@ -124,9 +129,6 @@ void __init board_setup(void)
#ifdef CONFIG_MIPS_DB1200
printk(KERN_INFO "AMD Alchemy Db1200 Board\n");
#endif
-
- /* Setup Pb1200 External Interrupt Controller */
- board_init_irq = _board_init_irq;
}
int board_au1200fb_panel(void)
diff --git a/arch/mips/alchemy/pb1200/irqmap.c b/arch/mips/alchemy/devboards/pb1200/irqmap.c
index 2a505ad..fe47498 100644
--- a/arch/mips/alchemy/pb1200/irqmap.c
+++ b/arch/mips/alchemy/devboards/pb1200/irqmap.c
@@ -40,91 +40,65 @@
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
/* This is external interrupt cascade */
- { AU1000_GPIO_7, INTC_INT_LOW_LEVEL, 0 },
+ { AU1000_GPIO_7, IRQF_TRIGGER_LOW, 0 },
};
-int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
/*
* Support for External interrupts on the Pb1200 Development platform.
*/
-static volatile int pb1200_cascade_en;
-irqreturn_t pb1200_cascade_handler(int irq, void *dev_id)
+static void pb1200_cascade_handler(unsigned int irq, struct irq_desc *d)
{
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 + __ffs(bisr);
- /* Ack and dispatch IRQ */
- do_IRQ(extirq_nr);
- }
-
- 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);
+ for ( ; bisr; bisr &= bisr - 1)
+ generic_handle_irq(PB1200_INT_BEGIN + __ffs(bisr));
}
-inline void pb1200_disable_irq(unsigned int irq_nr)
+/* NOTE: both the enable and mask bits must be cleared, otherwise the
+ * CPLD generates tons of spurious interrupts (at least on the DB1200).
+ */
+static void pb1200_mask_irq(unsigned int irq_nr)
{
bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN);
+ au_sync();
}
-static unsigned int pb1200_setup_cascade(void)
-{
- return request_irq(AU1000_GPIO_7, &pb1200_cascade_handler,
- 0, "Pb1200 Cascade", &pb1200_cascade_handler);
-}
-
-static unsigned int pb1200_startup_irq(unsigned int irq)
+static void pb1200_maskack_irq(unsigned int irq_nr)
{
- if (++pb1200_cascade_en == 1) {
- int res;
-
- res = pb1200_setup_cascade();
- if (res)
- return res;
- }
-
- pb1200_enable_irq(irq);
-
- return 0;
+ bcsr->intclr_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
+ bcsr->intclr = 1 << (irq_nr - PB1200_INT_BEGIN);
+ bcsr->int_status = 1 << (irq_nr - PB1200_INT_BEGIN); /* ack */
+ au_sync();
}
-static void pb1200_shutdown_irq(unsigned int irq)
+static void pb1200_unmask_irq(unsigned int irq_nr)
{
- pb1200_disable_irq(irq);
- if (--pb1200_cascade_en == 0)
- free_irq(AU1000_GPIO_7, &pb1200_cascade_handler);
+ bcsr->intset = 1 << (irq_nr - PB1200_INT_BEGIN);
+ bcsr->intset_mask = 1 << (irq_nr - PB1200_INT_BEGIN);
+ au_sync();
}
-static struct irq_chip external_irq_type = {
+static struct irq_chip pb1200_cpld_irq_type = {
#ifdef CONFIG_MIPS_PB1200
.name = "Pb1200 Ext",
#endif
#ifdef CONFIG_MIPS_DB1200
.name = "Db1200 Ext",
#endif
- .startup = pb1200_startup_irq,
- .shutdown = pb1200_shutdown_irq,
- .ack = pb1200_disable_irq,
- .mask = pb1200_disable_irq,
- .mask_ack = pb1200_disable_irq,
- .unmask = pb1200_enable_irq,
+ .mask = pb1200_mask_irq,
+ .mask_ack = pb1200_maskack_irq,
+ .unmask = pb1200_unmask_irq,
};
-void _board_init_irq(void)
+void __init board_init_irq(void)
{
unsigned int irq;
+ au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
+
#ifdef CONFIG_MIPS_PB1200
/* We have a problem with CPLD rev 3. */
if (((bcsr->whoami & BCSR_WHOAMI_CPLD) >> 4) <= 3) {
@@ -146,15 +120,15 @@ void _board_init_irq(void)
panic("Game over. Your score is 0.");
}
#endif
+ /* mask & disable & ack all */
+ bcsr->intclr_mask = 0xffff;
+ bcsr->intclr = 0xffff;
+ bcsr->int_status = 0xffff;
+ au_sync();
- for (irq = PB1200_INT_BEGIN; irq <= PB1200_INT_END; irq++) {
- set_irq_chip_and_handler(irq, &external_irq_type,
- handle_level_irq);
- pb1200_disable_irq(irq);
- }
+ for (irq = PB1200_INT_BEGIN; irq <= PB1200_INT_END; irq++)
+ set_irq_chip_and_handler_name(irq, &pb1200_cpld_irq_type,
+ handle_level_irq, "level");
- /*
- * GPIO_7 can not be hooked here, so it is hooked upon first
- * request of any source attached to the cascade.
- */
+ set_irq_chained_handler(AU1000_GPIO_7, pb1200_cascade_handler);
}
diff --git a/arch/mips/alchemy/pb1200/platform.c b/arch/mips/alchemy/devboards/pb1200/platform.c
index 9530329..9530329 100644
--- a/arch/mips/alchemy/pb1200/platform.c
+++ b/arch/mips/alchemy/devboards/pb1200/platform.c
diff --git a/arch/mips/alchemy/pb1500/Makefile b/arch/mips/alchemy/devboards/pb1500/Makefile
index 602f38d..173b419 100644
--- a/arch/mips/alchemy/pb1500/Makefile
+++ b/arch/mips/alchemy/devboards/pb1500/Makefile
@@ -5,4 +5,4 @@
# Makefile for the Alchemy Semiconductor Pb1500 board.
#
-lib-y := init.o board_setup.o irqmap.o
+obj-y := board_setup.o
diff --git a/arch/mips/alchemy/pb1500/board_setup.c b/arch/mips/alchemy/devboards/pb1500/board_setup.c
index 035771c..fed3b09 100644
--- a/arch/mips/alchemy/pb1500/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1500/board_setup.c
@@ -25,20 +25,64 @@
#include <linux/init.h>
#include <linux/delay.h>
+#include <linux/interrupt.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1500.h>
+#include <prom.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 */
+};
+
+struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
+ { AU1500_GPIO_204, IRQF_TRIGGER_HIGH, 0 },
+ { AU1500_GPIO_201, IRQF_TRIGGER_LOW, 0 },
+ { AU1500_GPIO_202, IRQF_TRIGGER_LOW, 0 },
+ { AU1500_GPIO_203, IRQF_TRIGGER_LOW, 0 },
+ { AU1500_GPIO_205, IRQF_TRIGGER_LOW, 0 },
+};
+
+
+const char *get_system_type(void)
+{
+ return "Alchemy Pb1500";
+}
+
void board_reset(void)
{
/* Hit BCSR.RST_VDDI[SOFT_RESET] */
au_writel(0x00000000, PB1500_RST_VDDI);
}
+void __init board_init_irq(void)
+{
+ au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
+}
+
void __init board_setup(void)
{
u32 pin_func;
u32 sys_freqctrl, sys_clksrc;
+ char *argptr;
+
+ argptr = prom_getcmdline();
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ argptr = strstr(argptr, "console=");
+ if (argptr == NULL) {
+ argptr = prom_getcmdline();
+ strcat(argptr, " console=ttyS0,115200");
+ }
+#endif
+
+#if defined(CONFIG_SOUND_AU1X00) && !defined(CONFIG_SOC_AU1000)
+ /* au1000 does not support vra, au1500 and au1100 do */
+ strcat(argptr, " au1000_audio=vra");
+ argptr = prom_getcmdline();
+#endif
sys_clksrc = sys_freqctrl = pin_func = 0;
/* Set AUX clock to 12 MHz * 8 = 96 MHz */
diff --git a/arch/mips/alchemy/pb1550/Makefile b/arch/mips/alchemy/devboards/pb1550/Makefile
index 7d8beca..cff95bc 100644
--- a/arch/mips/alchemy/pb1550/Makefile
+++ b/arch/mips/alchemy/devboards/pb1550/Makefile
@@ -5,4 +5,4 @@
# Makefile for the Alchemy Semiconductor Pb1550 board.
#
-lib-y := init.o board_setup.o irqmap.o
+obj-y := board_setup.o
diff --git a/arch/mips/alchemy/pb1550/board_setup.c b/arch/mips/alchemy/devboards/pb1550/board_setup.c
index 0ed76b6..b6e9e7d 100644
--- a/arch/mips/alchemy/pb1550/board_setup.c
+++ b/arch/mips/alchemy/devboards/pb1550/board_setup.c
@@ -28,20 +28,54 @@
*/
#include <linux/init.h>
+#include <linux/interrupt.h>
#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-pb1x00/pb1550.h>
+#include <prom.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) */
+};
+
+struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
+ { AU1000_GPIO_0, IRQF_TRIGGER_LOW, 0 },
+ { AU1000_GPIO_1, IRQF_TRIGGER_LOW, 0 },
+};
+
+const char *get_system_type(void)
+{
+ return "Alchemy Pb1550";
+}
+
void board_reset(void)
{
/* Hit BCSR.SYSTEM[RESET] */
au_writew(au_readw(0xAF00001C) & ~BCSR_SYSTEM_RESET, 0xAF00001C);
}
+void __init board_init_irq(void)
+{
+ au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
+}
+
void __init board_setup(void)
{
u32 pin_func;
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ char *argptr;
+ argptr = prom_getcmdline();
+ argptr = strstr(argptr, "console=");
+ if (argptr == NULL) {
+ argptr = prom_getcmdline();
+ strcat(argptr, " console=ttyS0,115200");
+ }
+#endif
+
/*
* Enable PSC1 SYNC for AC'97. Normaly done in audio driver,
* but it is board specific code, so put it here.
diff --git a/arch/mips/alchemy/devboards/pm.c b/arch/mips/alchemy/devboards/pm.c
new file mode 100644
index 0000000..d5eb9c3
--- /dev/null
+++ b/arch/mips/alchemy/devboards/pm.c
@@ -0,0 +1,229 @@
+/*
+ * Alchemy Development Board example suspend userspace interface.
+ *
+ * (c) 2008 Manuel Lauss <mano@roarinelk.homelinux.net>
+ */
+
+#include <linux/init.h>
+#include <linux/kobject.h>
+#include <linux/suspend.h>
+#include <linux/sysfs.h>
+#include <asm/mach-au1x00/au1000.h>
+
+/*
+ * Generic suspend userspace interface for Alchemy development boards.
+ * This code exports a few sysfs nodes under /sys/power/db1x/ which
+ * can be used by userspace to en/disable all au1x-provided wakeup
+ * sources and configure the timeout after which the the TOYMATCH2 irq
+ * is to trigger a wakeup.
+ */
+
+
+static unsigned long db1x_pm_sleep_secs;
+static unsigned long db1x_pm_wakemsk;
+static unsigned long db1x_pm_last_wakesrc;
+
+static int db1x_pm_enter(suspend_state_t state)
+{
+ /* enable GPIO based wakeup */
+ au_writel(1, SYS_PININPUTEN);
+
+ /* clear and setup wake cause and source */
+ au_writel(0, SYS_WAKEMSK);
+ au_sync();
+ au_writel(0, SYS_WAKESRC);
+ au_sync();
+
+ au_writel(db1x_pm_wakemsk, SYS_WAKEMSK);
+ au_sync();
+
+ /* setup 1Hz-timer-based wakeup: wait for reg access */
+ while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20)
+ asm volatile ("nop");
+
+ au_writel(au_readl(SYS_TOYREAD) + db1x_pm_sleep_secs, SYS_TOYMATCH2);
+ au_sync();
+
+ /* wait for value to really hit the register */
+ while (au_readl(SYS_COUNTER_CNTRL) & SYS_CNTRL_M20)
+ asm volatile ("nop");
+
+ /* ...and now the sandman can come! */
+ au_sleep();
+
+ return 0;
+}
+
+static int db1x_pm_begin(suspend_state_t state)
+{
+ if (!db1x_pm_wakemsk) {
+ printk(KERN_ERR "db1x: no wakeup source activated!\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void db1x_pm_end(void)
+{
+ /* read and store wakeup source, the clear the register. To
+ * be able to clear it, WAKEMSK must be cleared first.
+ */
+ db1x_pm_last_wakesrc = au_readl(SYS_WAKESRC);
+
+ au_writel(0, SYS_WAKEMSK);
+ au_writel(0, SYS_WAKESRC);
+ au_sync();
+
+}
+
+static struct platform_suspend_ops db1x_pm_ops = {
+ .valid = suspend_valid_only_mem,
+ .begin = db1x_pm_begin,
+ .enter = db1x_pm_enter,
+ .end = db1x_pm_end,
+};
+
+#define ATTRCMP(x) (0 == strcmp(attr->attr.name, #x))
+
+static ssize_t db1x_pmattr_show(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ char *buf)
+{
+ int idx;
+
+ if (ATTRCMP(timer_timeout))
+ return sprintf(buf, "%lu\n", db1x_pm_sleep_secs);
+
+ else if (ATTRCMP(timer))
+ return sprintf(buf, "%u\n",
+ !!(db1x_pm_wakemsk & SYS_WAKEMSK_M2));
+
+ else if (ATTRCMP(wakesrc))
+ return sprintf(buf, "%lu\n", db1x_pm_last_wakesrc);
+
+ else if (ATTRCMP(gpio0) || ATTRCMP(gpio1) || ATTRCMP(gpio2) ||
+ ATTRCMP(gpio3) || ATTRCMP(gpio4) || ATTRCMP(gpio5) ||
+ ATTRCMP(gpio6) || ATTRCMP(gpio7)) {
+ idx = (attr->attr.name)[4] - '0';
+ return sprintf(buf, "%d\n",
+ !!(db1x_pm_wakemsk & SYS_WAKEMSK_GPIO(idx)));
+
+ } else if (ATTRCMP(wakemsk)) {
+ return sprintf(buf, "%08lx\n", db1x_pm_wakemsk);
+ }
+
+ return -ENOENT;
+}
+
+static ssize_t db1x_pmattr_store(struct kobject *kobj,
+ struct kobj_attribute *attr,
+ const char *instr,
+ size_t bytes)
+{
+ unsigned long l;
+ int tmp;
+
+ if (ATTRCMP(timer_timeout)) {
+ tmp = strict_strtoul(instr, 0, &l);
+ if (tmp)
+ return tmp;
+
+ db1x_pm_sleep_secs = l;
+
+ } else if (ATTRCMP(timer)) {
+ if (instr[0] != '0')
+ db1x_pm_wakemsk |= SYS_WAKEMSK_M2;
+ else
+ db1x_pm_wakemsk &= ~SYS_WAKEMSK_M2;
+
+ } else if (ATTRCMP(gpio0) || ATTRCMP(gpio1) || ATTRCMP(gpio2) ||
+ ATTRCMP(gpio3) || ATTRCMP(gpio4) || ATTRCMP(gpio5) ||
+ ATTRCMP(gpio6) || ATTRCMP(gpio7)) {
+ tmp = (attr->attr.name)[4] - '0';
+ if (instr[0] != '0') {
+ db1x_pm_wakemsk |= SYS_WAKEMSK_GPIO(tmp);
+ } else {
+ db1x_pm_wakemsk &= ~SYS_WAKEMSK_GPIO(tmp);
+ }
+
+ } else if (ATTRCMP(wakemsk)) {
+ tmp = strict_strtoul(instr, 0, &l);
+ if (tmp)
+ return tmp;
+
+ db1x_pm_wakemsk = l & 0x0000003f;
+
+ } else
+ bytes = -ENOENT;
+
+ return bytes;
+}
+
+#define ATTR(x) \
+ static struct kobj_attribute x##_attribute = \
+ __ATTR(x, 0664, db1x_pmattr_show, \
+ db1x_pmattr_store);
+
+ATTR(gpio0) /* GPIO-based wakeup enable */
+ATTR(gpio1)
+ATTR(gpio2)
+ATTR(gpio3)
+ATTR(gpio4)
+ATTR(gpio5)
+ATTR(gpio6)
+ATTR(gpio7)
+ATTR(timer) /* TOYMATCH2-based wakeup enable */
+ATTR(timer_timeout) /* timer-based wakeup timeout value, in seconds */
+ATTR(wakesrc) /* contents of SYS_WAKESRC after last wakeup */
+ATTR(wakemsk) /* direct access to SYS_WAKEMSK */
+
+#define ATTR_LIST(x) & x ## _attribute.attr
+static struct attribute *db1x_pmattrs[] = {
+ ATTR_LIST(gpio0),
+ ATTR_LIST(gpio1),
+ ATTR_LIST(gpio2),
+ ATTR_LIST(gpio3),
+ ATTR_LIST(gpio4),
+ ATTR_LIST(gpio5),
+ ATTR_LIST(gpio6),
+ ATTR_LIST(gpio7),
+ ATTR_LIST(timer),
+ ATTR_LIST(timer_timeout),
+ ATTR_LIST(wakesrc),
+ ATTR_LIST(wakemsk),
+ NULL, /* terminator */
+};
+
+static struct attribute_group db1x_pmattr_group = {
+ .name = "db1x",
+ .attrs = db1x_pmattrs,
+};
+
+/*
+ * Initialize suspend interface
+ */
+static int __init pm_init(void)
+{
+ /* init TOY to tick at 1Hz if not already done. No need to wait
+ * for confirmation since there's plenty of time from here to
+ * the next suspend cycle.
+ */
+ if (au_readl(SYS_TOYTRIM) != 32767) {
+ au_writel(32767, SYS_TOYTRIM);
+ au_sync();
+ }
+
+ db1x_pm_last_wakesrc = au_readl(SYS_WAKESRC);
+
+ au_writel(0, SYS_WAKESRC);
+ au_sync();
+ au_writel(0, SYS_WAKEMSK);
+ au_sync();
+
+ suspend_set_ops(&db1x_pm_ops);
+
+ return sysfs_create_group(power_kobj, &db1x_pmattr_group);
+}
+
+late_initcall(pm_init);
diff --git a/arch/mips/alchemy/pb1550/init.c b/arch/mips/alchemy/devboards/prom.c
index e1055a1..0042bd6 100644
--- a/arch/mips/alchemy/pb1550/init.c
+++ b/arch/mips/alchemy/devboards/prom.c
@@ -1,9 +1,9 @@
/*
+ * Common code used by all Alchemy develboards.
*
- * BRIEF MODULE DESCRIPTION
- * Pb1550 board setup
+ * Extracted from files which had this to say:
*
- * Copyright 2001, 2008 MontaVista Software Inc.
+ * Copyright 2000, 2008 MontaVista Software Inc.
* Author: MontaVista Software, Inc. <source@mvista.com>
*
* This program is free software; you can redistribute it and/or modify it
@@ -29,15 +29,19 @@
#include <linux/init.h>
#include <linux/kernel.h>
-
#include <asm/bootinfo.h>
-
+#include <asm/mach-au1x00/au1000.h>
#include <prom.h>
-const char *get_system_type(void)
-{
- return "Alchemy Pb1550";
-}
+#if defined(CONFIG_MIPS_PB1000) || defined(CONFIG_MIPS_DB1000) || \
+ defined(CONFIG_MIPS_PB1100) || defined(CONFIG_MIPS_DB1100) || \
+ defined(CONFIG_MIPS_PB1500) || defined(CONFIG_MIPS_DB1500) || \
+ defined(CONFIG_MIPS_BOSPORUS) || defined(CONFIG_MIPS_MIRAGE)
+#define ALCHEMY_BOARD_DEFAULT_MEMSIZE 0x04000000
+
+#else /* Au1550/Au1200-based develboards */
+#define ALCHEMY_BOARD_DEFAULT_MEMSIZE 0x08000000
+#endif
void __init prom_init(void)
{
@@ -51,8 +55,8 @@ void __init prom_init(void)
prom_init_cmdline();
memsize_str = prom_getenv("memsize");
if (!memsize_str)
- memsize = 0x08000000;
+ memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE;
else
- strict_strtol(memsize_str, 0, &memsize);
+ strict_strtoul(memsize_str, 0, &memsize);
add_memory_region(0, memsize, BOOT_MEM_RAM);
}
diff --git a/arch/mips/alchemy/mtx-1/board_setup.c b/arch/mips/alchemy/mtx-1/board_setup.c
index 3f80791..8ed1ae1 100644
--- a/arch/mips/alchemy/mtx-1/board_setup.c
+++ b/arch/mips/alchemy/mtx-1/board_setup.c
@@ -32,6 +32,8 @@
#include <asm/mach-au1x00/au1000.h>
+#include <prom.h>
+
extern int (*board_pci_idsel)(unsigned int devsel, int assert);
int mtx1_pci_idsel(unsigned int devsel, int assert);
@@ -43,6 +45,16 @@ void board_reset(void)
void __init board_setup(void)
{
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ char *argptr;
+ argptr = prom_getcmdline();
+ argptr = strstr(argptr, "console=");
+ if (argptr == NULL) {
+ argptr = prom_getcmdline();
+ strcat(argptr, " console=ttyS0,115200");
+ }
+#endif
+
#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
/* Enable USB power switch */
au_writel(au_readl(GPIO2_DIR) | 0x10, GPIO2_DIR);
diff --git a/arch/mips/alchemy/mtx-1/init.c b/arch/mips/alchemy/mtx-1/init.c
index 3bae13c..5e871c8 100644
--- a/arch/mips/alchemy/mtx-1/init.c
+++ b/arch/mips/alchemy/mtx-1/init.c
@@ -55,6 +55,6 @@ void __init prom_init(void)
if (!memsize_str)
memsize = 0x04000000;
else
- strict_strtol(memsize_str, 0, &memsize);
+ strict_strtoul(memsize_str, 0, &memsize);
add_memory_region(0, memsize, BOOT_MEM_RAM);
}
diff --git a/arch/mips/alchemy/mtx-1/irqmap.c b/arch/mips/alchemy/mtx-1/irqmap.c
index f2bf029..f1ab12a 100644
--- a/arch/mips/alchemy/mtx-1/irqmap.c
+++ b/arch/mips/alchemy/mtx-1/irqmap.c
@@ -27,7 +27,7 @@
*/
#include <linux/init.h>
-
+#include <linux/interrupt.h>
#include <asm/mach-au1x00/au1000.h>
char irq_tab_alchemy[][5] __initdata = {
@@ -42,11 +42,15 @@ char irq_tab_alchemy[][5] __initdata = {
};
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
- { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 },
- { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
- { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
- { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
- { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 },
+ { AU1500_GPIO_204, IRQF_TRIGGER_HIGH, 0 },
+ { AU1500_GPIO_201, IRQF_TRIGGER_LOW, 0 },
+ { AU1500_GPIO_202, IRQF_TRIGGER_LOW, 0 },
+ { AU1500_GPIO_203, IRQF_TRIGGER_LOW, 0 },
+ { AU1500_GPIO_205, IRQF_TRIGGER_LOW, 0 },
};
-int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
+
+void __init board_init_irq(void)
+{
+ au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
+}
diff --git a/arch/mips/alchemy/pb1000/init.c b/arch/mips/alchemy/pb1000/init.c
deleted file mode 100644
index 8a9c7d5..0000000
--- a/arch/mips/alchemy/pb1000/init.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- * Pb1000 board setup
- *
- * Copyright 2001, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <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/kernel.h>
-
-#include <asm/bootinfo.h>
-
-#include <prom.h>
-
-const char *get_system_type(void)
-{
- return "Alchemy Pb1000";
-}
-
-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;
-
- prom_init_cmdline();
- memsize_str = prom_getenv("memsize");
- if (!memsize_str)
- memsize = 0x04000000;
- else
- strict_strtol(memsize_str, 0, &memsize);
- add_memory_region(0, memsize, BOOT_MEM_RAM);
-}
diff --git a/arch/mips/alchemy/pb1000/irqmap.c b/arch/mips/alchemy/pb1000/irqmap.c
deleted file mode 100644
index b3d56b0..0000000
--- a/arch/mips/alchemy/pb1000/irqmap.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- * Au1xxx irq map table
- *
- * Copyright 2003 Embedded Edge, LLC
- * dan@embeddededge.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/interrupt.h>
-
-#include <asm/mach-au1x00/au1000.h>
-
-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
- { AU1000_GPIO_15, INTC_INT_LOW_LEVEL, 0 },
-};
-
-int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
diff --git a/arch/mips/alchemy/pb1100/init.c b/arch/mips/alchemy/pb1100/init.c
deleted file mode 100644
index 7c67923..0000000
--- a/arch/mips/alchemy/pb1100/init.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- * Pb1100 board setup
- *
- * Copyright 2002, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <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/kernel.h>
-
-#include <asm/bootinfo.h>
-
-#include <prom.h>
-
-const char *get_system_type(void)
-{
- return "Alchemy Pb1100";
-}
-
-void __init prom_init(void)
-{
- unsigned char *memsize_str;
- unsigned long memsize;
-
- prom_argc = fw_arg0;
- prom_argv = (char **)fw_arg1;
- prom_envp = (char **)fw_arg3;
-
- prom_init_cmdline();
-
- memsize_str = prom_getenv("memsize");
- if (!memsize_str)
- memsize = 0x04000000;
- else
- strict_strtol(memsize_str, 0, &memsize);
-
- add_memory_region(0, memsize, BOOT_MEM_RAM);
-}
diff --git a/arch/mips/alchemy/pb1100/irqmap.c b/arch/mips/alchemy/pb1100/irqmap.c
deleted file mode 100644
index 9b7dd8b..0000000
--- a/arch/mips/alchemy/pb1100/irqmap.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- * Au1xx0 IRQ map table
- *
- * Copyright 2003 Embedded Edge, LLC
- * dan@embeddededge.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 <asm/mach-au1x00/au1000.h>
-
-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
- { AU1000_GPIO_9, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card Fully_Inserted# */
- { AU1000_GPIO_10, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card STSCHG# */
- { AU1000_GPIO_11, INTC_INT_LOW_LEVEL, 0 }, /* PCMCIA Card IRQ# */
- { AU1000_GPIO_13, INTC_INT_LOW_LEVEL, 0 }, /* DC_IRQ# */
-};
-
-int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
diff --git a/arch/mips/alchemy/pb1200/init.c b/arch/mips/alchemy/pb1200/init.c
deleted file mode 100644
index e9b2a0f..0000000
--- a/arch/mips/alchemy/pb1200/init.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- * PB1200 board setup
- *
- * Copyright 2001, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <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/kernel.h>
-
-#include <asm/bootinfo.h>
-
-#include <prom.h>
-
-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;
-
- prom_init_cmdline();
- memsize_str = prom_getenv("memsize");
- if (!memsize_str)
- memsize = 0x08000000;
- else
- strict_strtol(memsize_str, 0, &memsize);
- add_memory_region(0, memsize, BOOT_MEM_RAM);
-}
diff --git a/arch/mips/alchemy/pb1500/init.c b/arch/mips/alchemy/pb1500/init.c
deleted file mode 100644
index 3b6e395..0000000
--- a/arch/mips/alchemy/pb1500/init.c
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- * Pb1500 board setup
- *
- * Copyright 2001, 2008 MontaVista Software Inc.
- * Author: MontaVista Software, Inc. <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/kernel.h>
-
-#include <asm/bootinfo.h>
-
-#include <prom.h>
-
-const char *get_system_type(void)
-{
- return "Alchemy Pb1500";
-}
-
-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;
-
- prom_init_cmdline();
- memsize_str = prom_getenv("memsize");
- if (!memsize_str)
- memsize = 0x04000000;
- else
- strict_strtol(memsize_str, 0, &memsize);
- add_memory_region(0, memsize, BOOT_MEM_RAM);
-}
diff --git a/arch/mips/alchemy/pb1500/irqmap.c b/arch/mips/alchemy/pb1500/irqmap.c
deleted file mode 100644
index 39c4682..0000000
--- a/arch/mips/alchemy/pb1500/irqmap.c
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- * Au1xxx irq map table
- *
- * Copyright 2003 Embedded Edge, LLC
- * dan@embeddededge.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 <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 */
-};
-
-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
- { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 },
- { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
- { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
- { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
- { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 },
-};
-
-int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
diff --git a/arch/mips/alchemy/pb1550/irqmap.c b/arch/mips/alchemy/pb1550/irqmap.c
deleted file mode 100644
index a02a4d1..0000000
--- a/arch/mips/alchemy/pb1550/irqmap.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * BRIEF MODULE DESCRIPTION
- * Au1xx0 IRQ map table
- *
- * Copyright 2003 Embedded Edge, LLC
- * dan@embeddededge.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 <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) */
-};
-
-struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
- { AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 },
- { AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 },
-};
-
-int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
diff --git a/arch/mips/alchemy/xxs1500/board_setup.c b/arch/mips/alchemy/xxs1500/board_setup.c
index 4c587ac..a2634fa 100644
--- a/arch/mips/alchemy/xxs1500/board_setup.c
+++ b/arch/mips/alchemy/xxs1500/board_setup.c
@@ -28,6 +28,8 @@
#include <asm/mach-au1x00/au1000.h>
+#include <prom.h>
+
void board_reset(void)
{
/* Hit BCSR.SYSTEM_CONTROL[SW_RST] */
@@ -38,6 +40,16 @@ void __init board_setup(void)
{
u32 pin_func;
+#ifdef CONFIG_SERIAL_8250_CONSOLE
+ char *argptr;
+ argptr = prom_getcmdline();
+ argptr = strstr(argptr, "console=");
+ if (argptr == NULL) {
+ argptr = prom_getcmdline();
+ strcat(argptr, " console=ttyS0,115200");
+ }
+#endif
+
/* Set multiple use pins (UART3/GPIO) to UART (it's used as UART too) */
pin_func = au_readl(SYS_PINFUNC) & ~SYS_PF_UR3;
pin_func |= SYS_PF_UR3;
diff --git a/arch/mips/alchemy/xxs1500/init.c b/arch/mips/alchemy/xxs1500/init.c
index 7516434..456fa14 100644
--- a/arch/mips/alchemy/xxs1500/init.c
+++ b/arch/mips/alchemy/xxs1500/init.c
@@ -53,6 +53,6 @@ void __init prom_init(void)
if (!memsize_str)
memsize = 0x04000000;
else
- strict_strtol(memsize_str, 0, &memsize);
+ strict_strtoul(memsize_str, 0, &memsize);
add_memory_region(0, memsize, BOOT_MEM_RAM);
}
diff --git a/arch/mips/alchemy/xxs1500/irqmap.c b/arch/mips/alchemy/xxs1500/irqmap.c
index edf06ed..0f0f301 100644
--- a/arch/mips/alchemy/xxs1500/irqmap.c
+++ b/arch/mips/alchemy/xxs1500/irqmap.c
@@ -27,23 +27,26 @@
*/
#include <linux/init.h>
-
+#include <linux/interrupt.h>
#include <asm/mach-au1x00/au1000.h>
struct au1xxx_irqmap __initdata au1xxx_irq_map[] = {
- { AU1500_GPIO_204, INTC_INT_HIGH_LEVEL, 0 },
- { AU1500_GPIO_201, INTC_INT_LOW_LEVEL, 0 },
- { AU1500_GPIO_202, INTC_INT_LOW_LEVEL, 0 },
- { AU1500_GPIO_203, INTC_INT_LOW_LEVEL, 0 },
- { AU1500_GPIO_205, INTC_INT_LOW_LEVEL, 0 },
- { AU1500_GPIO_207, INTC_INT_LOW_LEVEL, 0 },
+ { AU1500_GPIO_204, IRQF_TRIGGER_HIGH, 0 },
+ { AU1500_GPIO_201, IRQF_TRIGGER_LOW, 0 },
+ { AU1500_GPIO_202, IRQF_TRIGGER_LOW, 0 },
+ { AU1500_GPIO_203, IRQF_TRIGGER_LOW, 0 },
+ { AU1500_GPIO_205, IRQF_TRIGGER_LOW, 0 },
+ { AU1500_GPIO_207, IRQF_TRIGGER_LOW, 0 },
- { AU1000_GPIO_0, INTC_INT_LOW_LEVEL, 0 },
- { AU1000_GPIO_1, INTC_INT_LOW_LEVEL, 0 },
- { AU1000_GPIO_2, INTC_INT_LOW_LEVEL, 0 },
- { AU1000_GPIO_3, INTC_INT_LOW_LEVEL, 0 },
- { AU1000_GPIO_4, INTC_INT_LOW_LEVEL, 0 }, /* CF interrupt */
- { AU1000_GPIO_5, INTC_INT_LOW_LEVEL, 0 },
+ { AU1000_GPIO_0, IRQF_TRIGGER_LOW, 0 },
+ { AU1000_GPIO_1, IRQF_TRIGGER_LOW, 0 },
+ { AU1000_GPIO_2, IRQF_TRIGGER_LOW, 0 },
+ { AU1000_GPIO_3, IRQF_TRIGGER_LOW, 0 },
+ { AU1000_GPIO_4, IRQF_TRIGGER_LOW, 0 }, /* CF interrupt */
+ { AU1000_GPIO_5, IRQF_TRIGGER_LOW, 0 },
};
-int __initdata au1xxx_nr_irqs = ARRAY_SIZE(au1xxx_irq_map);
+void __init board_init_irq(void)
+{
+ au1xxx_setup_irqmap(au1xxx_irq_map, ARRAY_SIZE(au1xxx_irq_map));
+}
diff --git a/arch/mips/cavium-octeon/Kconfig b/arch/mips/cavium-octeon/Kconfig
new file mode 100644
index 0000000..094c17e
--- /dev/null
+++ b/arch/mips/cavium-octeon/Kconfig
@@ -0,0 +1,85 @@
+config CAVIUM_OCTEON_SPECIFIC_OPTIONS
+ bool "Enable Octeon specific options"
+ depends on CPU_CAVIUM_OCTEON
+ default "y"
+
+config CAVIUM_OCTEON_2ND_KERNEL
+ bool "Build the kernel to be used as a 2nd kernel on the same chip"
+ depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS
+ default "n"
+ help
+ This option configures this kernel to be linked at a different
+ address and use the 2nd uart for output. This allows a kernel built
+ with this option to be run at the same time as one built without this
+ option.
+
+config CAVIUM_OCTEON_HW_FIX_UNALIGNED
+ bool "Enable hardware fixups of unaligned loads and stores"
+ depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS
+ default "y"
+ help
+ Configure the Octeon hardware to automatically fix unaligned loads
+ and stores. Normally unaligned accesses are fixed using a kernel
+ exception handler. This option enables the hardware automatic fixups,
+ which requires only an extra 3 cycles. Disable this option if you
+ are running code that relies on address exceptions on unaligned
+ accesses.
+
+config CAVIUM_OCTEON_CVMSEG_SIZE
+ int "Number of L1 cache lines reserved for CVMSEG memory"
+ depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS
+ range 0 54
+ default 1
+ help
+ CVMSEG LM is a segment that accesses portions of the dcache as a
+ local memory; the larger CVMSEG is, the smaller the cache is.
+ This selects the size of CVMSEG LM, which is in cache blocks. The
+ legally range is from zero to 54 cache blocks (i.e. CVMSEG LM is
+ between zero and 6192 bytes).
+
+config CAVIUM_OCTEON_LOCK_L2
+ bool "Lock often used kernel code in the L2"
+ depends on CAVIUM_OCTEON_SPECIFIC_OPTIONS
+ default "y"
+ help
+ Enable locking parts of the kernel into the L2 cache.
+
+config CAVIUM_OCTEON_LOCK_L2_TLB
+ bool "Lock the TLB handler in L2"
+ depends on CAVIUM_OCTEON_LOCK_L2
+ default "y"
+ help
+ Lock the low level TLB fast path into L2.
+
+config CAVIUM_OCTEON_LOCK_L2_EXCEPTION
+ bool "Lock the exception handler in L2"
+ depends on CAVIUM_OCTEON_LOCK_L2
+ default "y"
+ help
+ Lock the low level exception handler into L2.
+
+config CAVIUM_OCTEON_LOCK_L2_LOW_LEVEL_INTERRUPT
+ bool "Lock the interrupt handler in L2"
+ depends on CAVIUM_OCTEON_LOCK_L2
+ default "y"
+ help
+ Lock the low level interrupt handler into L2.
+
+config CAVIUM_OCTEON_LOCK_L2_INTERRUPT
+ bool "Lock the 2nd level interrupt handler in L2"
+ depends on CAVIUM_OCTEON_LOCK_L2
+ default "y"
+ help
+ Lock the 2nd level interrupt handler in L2.
+
+config CAVIUM_OCTEON_LOCK_L2_MEMCPY
+ bool "Lock memcpy() in L2"
+ depends on CAVIUM_OCTEON_LOCK_L2
+ default "y"
+ help
+ Lock the kernel's implementation of memcpy() into L2.
+
+config ARCH_SPARSEMEM_ENABLE
+ def_bool y
+ select SPARSEMEM_STATIC
+ depends on CPU_CAVIUM_OCTEON
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
new file mode 100644
index 0000000..1c2a7fa
--- /dev/null
+++ b/arch/mips/cavium-octeon/Makefile
@@ -0,0 +1,16 @@
+#
+# Makefile for the Cavium Octeon specific kernel interface routines
+# under Linux.
+#
+# 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-2008 Cavium Networks
+#
+
+obj-y := setup.o serial.o octeon-irq.o csrc-octeon.o
+obj-y += dma-octeon.o flash_setup.o
+obj-y += octeon-memcpy.o
+
+obj-$(CONFIG_SMP) += smp.o
diff --git a/arch/mips/cavium-octeon/csrc-octeon.c b/arch/mips/cavium-octeon/csrc-octeon.c
new file mode 100644
index 0000000..70fd92c
--- /dev/null
+++ b/arch/mips/cavium-octeon/csrc-octeon.c
@@ -0,0 +1,58 @@
+/*
+ * 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) 2007 by Ralf Baechle
+ */
+#include <linux/clocksource.h>
+#include <linux/init.h>
+
+#include <asm/time.h>
+
+#include <asm/octeon/octeon.h>
+#include <asm/octeon/cvmx-ipd-defs.h>
+
+/*
+ * Set the current core's cvmcount counter to the value of the
+ * IPD_CLK_COUNT. We do this on all cores as they are brought
+ * on-line. This allows for a read from a local cpu register to
+ * access a synchronized counter.
+ *
+ */
+void octeon_init_cvmcount(void)
+{
+ unsigned long flags;
+ unsigned loops = 2;
+
+ /* Clobber loops so GCC will not unroll the following while loop. */
+ asm("" : "+r" (loops));
+
+ local_irq_save(flags);
+ /*
+ * Loop several times so we are executing from the cache,
+ * which should give more deterministic timing.
+ */
+ while (loops--)
+ write_c0_cvmcount(cvmx_read_csr(CVMX_IPD_CLK_COUNT));
+ local_irq_restore(flags);
+}
+
+static cycle_t octeon_cvmcount_read(void)
+{
+ return read_c0_cvmcount();
+}
+
+static struct clocksource clocksource_mips = {
+ .name = "OCTEON_CVMCOUNT",
+ .read = octeon_cvmcount_read,
+ .mask = CLOCKSOURCE_MASK(64),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+void __init plat_time_init(void)
+{
+ clocksource_mips.rating = 300;
+ clocksource_set_clock(&clocksource_mips, mips_hpt_frequency);
+ clocksource_register(&clocksource_mips);
+}
diff --git a/arch/mips/cavium-octeon/dma-octeon.c b/arch/mips/cavium-octeon/dma-octeon.c
new file mode 100644
index 0000000..01b1ef9
--- /dev/null
+++ b/arch/mips/cavium-octeon/dma-octeon.c
@@ -0,0 +1,32 @@
+/*
+ * 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 Ani Joshi <ajoshi@unixbox.com>
+ * Copyright (C) 2000, 2001 Ralf Baechle <ralf@gnu.org>
+ * Copyright (C) 2005 Ilya A. Volynets-Evenbakh <ilya@total-knowledge.com>
+ * swiped from i386, and cloned for MIPS by Geert, polished by Ralf.
+ * IP32 changes by Ilya.
+ * Cavium Networks: Create new dma setup for Cavium Networks Octeon based on
+ * the kernels original.
+ */
+#include <linux/types.h>
+#include <linux/mm.h>
+
+#include <dma-coherence.h>
+
+dma_addr_t octeon_map_dma_mem(struct device *dev, void *ptr, size_t size)
+{
+ /* Without PCI/PCIe this function can be called for Octeon internal
+ devices such as USB. These devices all support 64bit addressing */
+ mb();
+ return virt_to_phys(ptr);
+}
+
+void octeon_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
+{
+ /* Without PCI/PCIe this function can be called for Octeon internal
+ * devices such as USB. These devices all support 64bit addressing */
+ return;
+}
diff --git a/arch/mips/cavium-octeon/executive/Makefile b/arch/mips/cavium-octeon/executive/Makefile
new file mode 100644
index 0000000..80d6cb2
--- /dev/null
+++ b/arch/mips/cavium-octeon/executive/Makefile
@@ -0,0 +1,13 @@
+#
+# Makefile for the Cavium Octeon specific kernel interface routines
+# under Linux.
+#
+# 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-2008 Cavium Networks
+#
+
+obj-y += cvmx-bootmem.o cvmx-l2c.o cvmx-sysinfo.o octeon-model.o
+
diff --git a/arch/mips/cavium-octeon/executive/cvmx-bootmem.c b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
new file mode 100644
index 0000000..4f5a08b
--- /dev/null
+++ b/arch/mips/cavium-octeon/executive/cvmx-bootmem.c
@@ -0,0 +1,586 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Simple allocate only memory allocator. Used to allocate memory at
+ * application start time.
+ */
+
+#include <linux/kernel.h>
+
+#include <asm/octeon/cvmx.h>
+#include <asm/octeon/cvmx-spinlock.h>
+#include <asm/octeon/cvmx-bootmem.h>
+
+/*#define DEBUG */
+
+
+static struct cvmx_bootmem_desc *cvmx_bootmem_desc;
+
+/* See header file for descriptions of functions */
+
+/*
+ * Wrapper functions are provided for reading/writing the size and
+ * next block values as these may not be directly addressible (in 32
+ * bit applications, for instance.) Offsets of data elements in
+ * bootmem list, must match cvmx_bootmem_block_header_t.
+ */
+#define NEXT_OFFSET 0
+#define SIZE_OFFSET 8
+
+static void cvmx_bootmem_phy_set_size(uint64_t addr, uint64_t size)
+{
+ cvmx_write64_uint64((addr + SIZE_OFFSET) | (1ull << 63), size);
+}
+
+static void cvmx_bootmem_phy_set_next(uint64_t addr, uint64_t next)
+{
+ cvmx_write64_uint64((addr + NEXT_OFFSET) | (1ull << 63), next);
+}
+
+static uint64_t cvmx_bootmem_phy_get_size(uint64_t addr)
+{
+ return cvmx_read64_uint64((addr + SIZE_OFFSET) | (1ull << 63));
+}
+
+static uint64_t cvmx_bootmem_phy_get_next(uint64_t addr)
+{
+ return cvmx_read64_uint64((addr + NEXT_OFFSET) | (1ull << 63));
+}
+
+void *cvmx_bootmem_alloc_range(uint64_t size, uint64_t alignment,
+ uint64_t min_addr, uint64_t max_addr)
+{
+ int64_t address;
+ address =
+ cvmx_bootmem_phy_alloc(size, min_addr, max_addr, alignment, 0);
+
+ if (address > 0)
+ return cvmx_phys_to_ptr(address);
+ else
+ return NULL;
+}
+
+void *cvmx_bootmem_alloc_address(uint64_t size, uint64_t address,
+ uint64_t alignment)
+{
+ return cvmx_bootmem_alloc_range(size, alignment, address,
+ address + size);
+}
+
+void *cvmx_bootmem_alloc(uint64_t size, uint64_t alignment)
+{
+ return cvmx_bootmem_alloc_range(size, alignment, 0, 0);
+}
+
+int cvmx_bootmem_free_named(char *name)
+{
+ return cvmx_bootmem_phy_named_block_free(name, 0);
+}
+
+struct cvmx_bootmem_named_block_desc *cvmx_bootmem_find_named_block(char *name)
+{
+ return cvmx_bootmem_phy_named_block_find(name, 0);
+}
+
+void cvmx_bootmem_lock(void)
+{
+ cvmx_spinlock_lock((cvmx_spinlock_t *) &(cvmx_bootmem_desc->lock));
+}
+
+void cvmx_bootmem_unlock(void)
+{
+ cvmx_spinlock_unlock((cvmx_spinlock_t *) &(cvmx_bootmem_desc->lock));
+}
+
+int cvmx_bootmem_init(void *mem_desc_ptr)
+{
+ /* Here we set the global pointer to the bootmem descriptor
+ * block. This pointer will be used directly, so we will set
+ * it up to be directly usable by the application. It is set
+ * up as follows for the various runtime/ABI combinations:
+ *
+ * Linux 64 bit: Set XKPHYS bit
+ * Linux 32 bit: use mmap to create mapping, use virtual address
+ * CVMX 64 bit: use physical address directly
+ * CVMX 32 bit: use physical address directly
+ *
+ * Note that the CVMX environment assumes the use of 1-1 TLB
+ * mappings so that the physical addresses can be used
+ * directly
+ */
+ if (!cvmx_bootmem_desc) {
+#if defined(CVMX_ABI_64)
+ /* Set XKPHYS bit */
+ cvmx_bootmem_desc = cvmx_phys_to_ptr(CAST64(mem_desc_ptr));
+#else
+ cvmx_bootmem_desc = (struct cvmx_bootmem_desc *) mem_desc_ptr;
+#endif
+ }
+
+ return 0;
+}
+
+/*
+ * The cvmx_bootmem_phy* functions below return 64 bit physical
+ * addresses, and expose more features that the cvmx_bootmem_functions
+ * above. These are required for full memory space access in 32 bit
+ * applications, as well as for using some advance features. Most
+ * applications should not need to use these.
+ */
+
+int64_t cvmx_bootmem_phy_alloc(uint64_t req_size, uint64_t address_min,
+ uint64_t address_max, uint64_t alignment,
+ uint32_t flags)
+{
+
+ uint64_t head_addr;
+ uint64_t ent_addr;
+ /* points to previous list entry, NULL current entry is head of list */
+ uint64_t prev_addr = 0;
+ uint64_t new_ent_addr = 0;
+ uint64_t desired_min_addr;
+
+#ifdef DEBUG
+ cvmx_dprintf("cvmx_bootmem_phy_alloc: req_size: 0x%llx, "
+ "min_addr: 0x%llx, max_addr: 0x%llx, align: 0x%llx\n",
+ (unsigned long long)req_size,
+ (unsigned long long)address_min,
+ (unsigned long long)address_max,
+ (unsigned long long)alignment);
+#endif
+
+ if (cvmx_bootmem_desc->major_version > 3) {
+ cvmx_dprintf("ERROR: Incompatible bootmem descriptor "
+ "version: %d.%d at addr: %p\n",
+ (int)cvmx_bootmem_desc->major_version,
+ (int)cvmx_bootmem_desc->minor_version,
+ cvmx_bootmem_desc);
+ goto error_out;
+ }
+
+ /*
+ * Do a variety of checks to validate the arguments. The
+ * allocator code will later assume that these checks have
+ * been made. We validate that the requested constraints are
+ * not self-contradictory before we look through the list of
+ * available memory.
+ */
+
+ /* 0 is not a valid req_size for this allocator */
+ if (!req_size)
+ goto error_out;
+
+ /* Round req_size up to mult of minimum alignment bytes */
+ req_size = (req_size + (CVMX_BOOTMEM_ALIGNMENT_SIZE - 1)) &
+ ~(CVMX_BOOTMEM_ALIGNMENT_SIZE - 1);
+
+ /*
+ * Convert !0 address_min and 0 address_max to special case of
+ * range that specifies an exact memory block to allocate. Do
+ * this before other checks and adjustments so that this
+ * tranformation will be validated.
+ */
+ if (address_min && !address_max)
+ address_max = address_min + req_size;
+ else if (!address_min && !address_max)
+ address_max = ~0ull; /* If no limits given, use max limits */
+
+
+ /*
+ * Enforce minimum alignment (this also keeps the minimum free block
+ * req_size the same as the alignment req_size.
+ */
+ if (alignment < CVMX_BOOTMEM_ALIGNMENT_SIZE)
+ alignment = CVMX_BOOTMEM_ALIGNMENT_SIZE;
+
+ /*
+ * Adjust address minimum based on requested alignment (round
+ * up to meet alignment). Do this here so we can reject
+ * impossible requests up front. (NOP for address_min == 0)
+ */
+ if (alignment)
+ address_min = __ALIGN_MASK(address_min, (alignment - 1));
+
+ /*
+ * Reject inconsistent args. We have adjusted these, so this
+ * may fail due to our internal changes even if this check
+ * would pass for the values the user supplied.
+ */
+ if (req_size > address_max - address_min)
+ goto error_out;
+
+ /* Walk through the list entries - first fit found is returned */
+
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_bootmem_lock();
+ head_addr = cvmx_bootmem_desc->head_addr;
+ ent_addr = head_addr;
+ for (; ent_addr;
+ prev_addr = ent_addr,
+ ent_addr = cvmx_bootmem_phy_get_next(ent_addr)) {
+ uint64_t usable_base, usable_max;
+ uint64_t ent_size = cvmx_bootmem_phy_get_size(ent_addr);
+
+ if (cvmx_bootmem_phy_get_next(ent_addr)
+ && ent_addr > cvmx_bootmem_phy_get_next(ent_addr)) {
+ cvmx_dprintf("Internal bootmem_alloc() error: ent: "
+ "0x%llx, next: 0x%llx\n",
+ (unsigned long long)ent_addr,
+ (unsigned long long)
+ cvmx_bootmem_phy_get_next(ent_addr));
+ goto error_out;
+ }
+
+ /*
+ * Determine if this is an entry that can satisify the
+ * request Check to make sure entry is large enough to
+ * satisfy request.
+ */
+ usable_base =
+ __ALIGN_MASK(max(address_min, ent_addr), alignment - 1);
+ usable_max = min(address_max, ent_addr + ent_size);
+ /*
+ * We should be able to allocate block at address
+ * usable_base.
+ */
+
+ desired_min_addr = usable_base;
+ /*
+ * Determine if request can be satisfied from the
+ * current entry.
+ */
+ if (!((ent_addr + ent_size) > usable_base
+ && ent_addr < address_max
+ && req_size <= usable_max - usable_base))
+ continue;
+ /*
+ * We have found an entry that has room to satisfy the
+ * request, so allocate it from this entry. If end
+ * CVMX_BOOTMEM_FLAG_END_ALLOC set, then allocate from
+ * the end of this block rather than the beginning.
+ */
+ if (flags & CVMX_BOOTMEM_FLAG_END_ALLOC) {
+ desired_min_addr = usable_max - req_size;
+ /*
+ * Align desired address down to required
+ * alignment.
+ */
+ desired_min_addr &= ~(alignment - 1);
+ }
+
+ /* Match at start of entry */
+ if (desired_min_addr == ent_addr) {
+ if (req_size < ent_size) {
+ /*
+ * big enough to create a new block
+ * from top portion of block.
+ */
+ new_ent_addr = ent_addr + req_size;
+ cvmx_bootmem_phy_set_next(new_ent_addr,
+ cvmx_bootmem_phy_get_next(ent_addr));
+ cvmx_bootmem_phy_set_size(new_ent_addr,
+ ent_size -
+ req_size);
+
+ /*
+ * Adjust next pointer as following
+ * code uses this.
+ */
+ cvmx_bootmem_phy_set_next(ent_addr,
+ new_ent_addr);
+ }
+
+ /*
+ * adjust prev ptr or head to remove this
+ * entry from list.
+ */
+ if (prev_addr)
+ cvmx_bootmem_phy_set_next(prev_addr,
+ cvmx_bootmem_phy_get_next(ent_addr));
+ else
+ /*
+ * head of list being returned, so
+ * update head ptr.
+ */
+ cvmx_bootmem_desc->head_addr =
+ cvmx_bootmem_phy_get_next(ent_addr);
+
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_bootmem_unlock();
+ return desired_min_addr;
+ }
+ /*
+ * block returned doesn't start at beginning of entry,
+ * so we know that we will be splitting a block off
+ * the front of this one. Create a new block from the
+ * beginning, add to list, and go to top of loop
+ * again.
+ *
+ * create new block from high portion of
+ * block, so that top block starts at desired
+ * addr.
+ */
+ new_ent_addr = desired_min_addr;
+ cvmx_bootmem_phy_set_next(new_ent_addr,
+ cvmx_bootmem_phy_get_next
+ (ent_addr));
+ cvmx_bootmem_phy_set_size(new_ent_addr,
+ cvmx_bootmem_phy_get_size
+ (ent_addr) -
+ (desired_min_addr -
+ ent_addr));
+ cvmx_bootmem_phy_set_size(ent_addr,
+ desired_min_addr - ent_addr);
+ cvmx_bootmem_phy_set_next(ent_addr, new_ent_addr);
+ /* Loop again to handle actual alloc from new block */
+ }
+error_out:
+ /* We didn't find anything, so return error */
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_bootmem_unlock();
+ return -1;
+}
+
+int __cvmx_bootmem_phy_free(uint64_t phy_addr, uint64_t size, uint32_t flags)
+{
+ uint64_t cur_addr;
+ uint64_t prev_addr = 0; /* zero is invalid */
+ int retval = 0;
+
+#ifdef DEBUG
+ cvmx_dprintf("__cvmx_bootmem_phy_free addr: 0x%llx, size: 0x%llx\n",
+ (unsigned long long)phy_addr, (unsigned long long)size);
+#endif
+ if (cvmx_bootmem_desc->major_version > 3) {
+ cvmx_dprintf("ERROR: Incompatible bootmem descriptor "
+ "version: %d.%d at addr: %p\n",
+ (int)cvmx_bootmem_desc->major_version,
+ (int)cvmx_bootmem_desc->minor_version,
+ cvmx_bootmem_desc);
+ return 0;
+ }
+
+ /* 0 is not a valid size for this allocator */
+ if (!size)
+ return 0;
+
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_bootmem_lock();
+ cur_addr = cvmx_bootmem_desc->head_addr;
+ if (cur_addr == 0 || phy_addr < cur_addr) {
+ /* add at front of list - special case with changing head ptr */
+ if (cur_addr && phy_addr + size > cur_addr)
+ goto bootmem_free_done; /* error, overlapping section */
+ else if (phy_addr + size == cur_addr) {
+ /* Add to front of existing first block */
+ cvmx_bootmem_phy_set_next(phy_addr,
+ cvmx_bootmem_phy_get_next
+ (cur_addr));
+ cvmx_bootmem_phy_set_size(phy_addr,
+ cvmx_bootmem_phy_get_size
+ (cur_addr) + size);
+ cvmx_bootmem_desc->head_addr = phy_addr;
+
+ } else {
+ /* New block before first block. OK if cur_addr is 0 */
+ cvmx_bootmem_phy_set_next(phy_addr, cur_addr);
+ cvmx_bootmem_phy_set_size(phy_addr, size);
+ cvmx_bootmem_desc->head_addr = phy_addr;
+ }
+ retval = 1;
+ goto bootmem_free_done;
+ }
+
+ /* Find place in list to add block */
+ while (cur_addr && phy_addr > cur_addr) {
+ prev_addr = cur_addr;
+ cur_addr = cvmx_bootmem_phy_get_next(cur_addr);
+ }
+
+ if (!cur_addr) {
+ /*
+ * We have reached the end of the list, add on to end,
+ * checking to see if we need to combine with last
+ * block
+ */
+ if (prev_addr + cvmx_bootmem_phy_get_size(prev_addr) ==
+ phy_addr) {
+ cvmx_bootmem_phy_set_size(prev_addr,
+ cvmx_bootmem_phy_get_size
+ (prev_addr) + size);
+ } else {
+ cvmx_bootmem_phy_set_next(prev_addr, phy_addr);
+ cvmx_bootmem_phy_set_size(phy_addr, size);
+ cvmx_bootmem_phy_set_next(phy_addr, 0);
+ }
+ retval = 1;
+ goto bootmem_free_done;
+ } else {
+ /*
+ * insert between prev and cur nodes, checking for
+ * merge with either/both.
+ */
+ if (prev_addr + cvmx_bootmem_phy_get_size(prev_addr) ==
+ phy_addr) {
+ /* Merge with previous */
+ cvmx_bootmem_phy_set_size(prev_addr,
+ cvmx_bootmem_phy_get_size
+ (prev_addr) + size);
+ if (phy_addr + size == cur_addr) {
+ /* Also merge with current */
+ cvmx_bootmem_phy_set_size(prev_addr,
+ cvmx_bootmem_phy_get_size(cur_addr) +
+ cvmx_bootmem_phy_get_size(prev_addr));
+ cvmx_bootmem_phy_set_next(prev_addr,
+ cvmx_bootmem_phy_get_next(cur_addr));
+ }
+ retval = 1;
+ goto bootmem_free_done;
+ } else if (phy_addr + size == cur_addr) {
+ /* Merge with current */
+ cvmx_bootmem_phy_set_size(phy_addr,
+ cvmx_bootmem_phy_get_size
+ (cur_addr) + size);
+ cvmx_bootmem_phy_set_next(phy_addr,
+ cvmx_bootmem_phy_get_next
+ (cur_addr));
+ cvmx_bootmem_phy_set_next(prev_addr, phy_addr);
+ retval = 1;
+ goto bootmem_free_done;
+ }
+
+ /* It is a standalone block, add in between prev and cur */
+ cvmx_bootmem_phy_set_size(phy_addr, size);
+ cvmx_bootmem_phy_set_next(phy_addr, cur_addr);
+ cvmx_bootmem_phy_set_next(prev_addr, phy_addr);
+
+ }
+ retval = 1;
+
+bootmem_free_done:
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_bootmem_unlock();
+ return retval;
+
+}
+
+struct cvmx_bootmem_named_block_desc *
+ cvmx_bootmem_phy_named_block_find(char *name, uint32_t flags)
+{
+ unsigned int i;
+ struct cvmx_bootmem_named_block_desc *named_block_array_ptr;
+
+#ifdef DEBUG
+ cvmx_dprintf("cvmx_bootmem_phy_named_block_find: %s\n", name);
+#endif
+ /*
+ * Lock the structure to make sure that it is not being
+ * changed while we are examining it.
+ */
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_bootmem_lock();
+
+ /* Use XKPHYS for 64 bit linux */
+ named_block_array_ptr = (struct cvmx_bootmem_named_block_desc *)
+ cvmx_phys_to_ptr(cvmx_bootmem_desc->named_block_array_addr);
+
+#ifdef DEBUG
+ cvmx_dprintf
+ ("cvmx_bootmem_phy_named_block_find: named_block_array_ptr: %p\n",
+ named_block_array_ptr);
+#endif
+ if (cvmx_bootmem_desc->major_version == 3) {
+ for (i = 0;
+ i < cvmx_bootmem_desc->named_block_num_blocks; i++) {
+ if ((name && named_block_array_ptr[i].size
+ && !strncmp(name, named_block_array_ptr[i].name,
+ cvmx_bootmem_desc->named_block_name_len
+ - 1))
+ || (!name && !named_block_array_ptr[i].size)) {
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_bootmem_unlock();
+
+ return &(named_block_array_ptr[i]);
+ }
+ }
+ } else {
+ cvmx_dprintf("ERROR: Incompatible bootmem descriptor "
+ "version: %d.%d at addr: %p\n",
+ (int)cvmx_bootmem_desc->major_version,
+ (int)cvmx_bootmem_desc->minor_version,
+ cvmx_bootmem_desc);
+ }
+ if (!(flags & CVMX_BOOTMEM_FLAG_NO_LOCKING))
+ cvmx_bootmem_unlock();
+
+ return NULL;
+}
+
+int cvmx_bootmem_phy_named_block_free(char *name, uint32_t flags)
+{
+ struct cvmx_bootmem_named_block_desc *named_block_ptr;
+
+ if (cvmx_bootmem_desc->major_version != 3) {
+ cvmx_dprintf("ERROR: Incompatible bootmem descriptor version: "
+ "%d.%d at addr: %p\n",
+ (int)cvmx_bootmem_desc->major_version,
+ (int)cvmx_bootmem_desc->minor_version,
+ cvmx_bootmem_desc);
+ return 0;
+ }
+#ifdef DEBUG
+ cvmx_dprintf("cvmx_bootmem_phy_named_block_free: %s\n", name);
+#endif
+
+ /*
+ * Take lock here, as name lookup/block free/name free need to
+ * be atomic.
+ */
+ cvmx_bootmem_lock();
+
+ named_block_ptr =
+ cvmx_bootmem_phy_named_block_find(name,
+ CVMX_BOOTMEM_FLAG_NO_LOCKING);
+ if (named_block_ptr) {
+#ifdef DEBUG
+ cvmx_dprintf("cvmx_bootmem_phy_named_block_free: "
+ "%s, base: 0x%llx, size: 0x%llx\n",
+ name,
+ (unsigned long long)named_block_ptr->base_addr,
+ (unsigned long long)named_block_ptr->size);
+#endif
+ __cvmx_bootmem_phy_free(named_block_ptr->base_addr,
+ named_block_ptr->size,
+ CVMX_BOOTMEM_FLAG_NO_LOCKING);
+ named_block_ptr->size = 0;
+ /* Set size to zero to indicate block not used. */
+ }
+
+ cvmx_bootmem_unlock();
+ return named_block_ptr != NULL; /* 0 on failure, 1 on success */
+}
diff --git a/arch/mips/cavium-octeon/executive/cvmx-l2c.c b/arch/mips/cavium-octeon/executive/cvmx-l2c.c
new file mode 100644
index 0000000..6abe56f
--- /dev/null
+++ b/arch/mips/cavium-octeon/executive/cvmx-l2c.c
@@ -0,0 +1,734 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Implementation of the Level 2 Cache (L2C) control, measurement, and
+ * debugging facilities.
+ */
+
+#include <asm/octeon/cvmx.h>
+#include <asm/octeon/cvmx-l2c.h>
+#include <asm/octeon/cvmx-spinlock.h>
+
+/*
+ * This spinlock is used internally to ensure that only one core is
+ * performing certain L2 operations at a time.
+ *
+ * NOTE: This only protects calls from within a single application -
+ * if multiple applications or operating systems are running, then it
+ * is up to the user program to coordinate between them.
+ */
+static cvmx_spinlock_t cvmx_l2c_spinlock;
+
+static inline int l2_size_half(void)
+{
+ uint64_t val = cvmx_read_csr(CVMX_L2D_FUS3);
+ return !!(val & (1ull << 34));
+}
+
+int cvmx_l2c_get_core_way_partition(uint32_t core)
+{
+ uint32_t field;
+
+ /* Validate the core number */
+ if (core >= cvmx_octeon_num_cores())
+ return -1;
+
+ /*
+ * Use the lower two bits of the coreNumber to determine the
+ * bit offset of the UMSK[] field in the L2C_SPAR register.
+ */
+ field = (core & 0x3) * 8;
+
+ /*
+ * Return the UMSK[] field from the appropriate L2C_SPAR
+ * register based on the coreNumber.
+ */
+
+ switch (core & 0xC) {
+ case 0x0:
+ return (cvmx_read_csr(CVMX_L2C_SPAR0) & (0xFF << field)) >>
+ field;
+ case 0x4:
+ return (cvmx_read_csr(CVMX_L2C_SPAR1) & (0xFF << field)) >>
+ field;
+ case 0x8:
+ return (cvmx_read_csr(CVMX_L2C_SPAR2) & (0xFF << field)) >>
+ field;
+ case 0xC:
+ return (cvmx_read_csr(CVMX_L2C_SPAR3) & (0xFF << field)) >>
+ field;
+ }
+ return 0;
+}
+
+int cvmx_l2c_set_core_way_partition(uint32_t core, uint32_t mask)
+{
+ uint32_t field;
+ uint32_t valid_mask;
+
+ valid_mask = (0x1 << cvmx_l2c_get_num_assoc()) - 1;
+
+ mask &= valid_mask;
+
+ /* A UMSK setting which blocks all L2C Ways is an error. */
+ if (mask == valid_mask)
+ return -1;
+
+ /* Validate the core number */
+ if (core >= cvmx_octeon_num_cores())
+ return -1;
+
+ /* Check to make sure current mask & new mask don't block all ways */
+ if (((mask | cvmx_l2c_get_core_way_partition(core)) & valid_mask) ==
+ valid_mask)
+ return -1;
+
+ /* Use the lower two bits of core to determine the bit offset of the
+ * UMSK[] field in the L2C_SPAR register.
+ */
+ field = (core & 0x3) * 8;
+
+ /* Assign the new mask setting to the UMSK[] field in the appropriate
+ * L2C_SPAR register based on the core_num.
+ *
+ */
+ switch (core & 0xC) {
+ case 0x0:
+ cvmx_write_csr(CVMX_L2C_SPAR0,
+ (cvmx_read_csr(CVMX_L2C_SPAR0) &
+ ~(0xFF << field)) | mask << field);
+ break;
+ case 0x4:
+ cvmx_write_csr(CVMX_L2C_SPAR1,
+ (cvmx_read_csr(CVMX_L2C_SPAR1) &
+ ~(0xFF << field)) | mask << field);
+ break;
+ case 0x8:
+ cvmx_write_csr(CVMX_L2C_SPAR2,
+ (cvmx_read_csr(CVMX_L2C_SPAR2) &
+ ~(0xFF << field)) | mask << field);
+ break;
+ case 0xC:
+ cvmx_write_csr(CVMX_L2C_SPAR3,
+ (cvmx_read_csr(CVMX_L2C_SPAR3) &
+ ~(0xFF << field)) | mask << field);
+ break;
+ }
+ return 0;
+}
+
+int cvmx_l2c_set_hw_way_partition(uint32_t mask)
+{
+ uint32_t valid_mask;
+
+ valid_mask = 0xff;
+
+ if (OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN38XX)) {
+ if (l2_size_half())
+ valid_mask = 0xf;
+ } else if (l2_size_half())
+ valid_mask = 0x3;
+
+ mask &= valid_mask;
+
+ /* A UMSK setting which blocks all L2C Ways is an error. */
+ if (mask == valid_mask)
+ return -1;
+ /* Check to make sure current mask & new mask don't block all ways */
+ if (((mask | cvmx_l2c_get_hw_way_partition()) & valid_mask) ==
+ valid_mask)
+ return -1;
+
+ cvmx_write_csr(CVMX_L2C_SPAR4,
+ (cvmx_read_csr(CVMX_L2C_SPAR4) & ~0xFF) | mask);
+ return 0;
+}
+
+int cvmx_l2c_get_hw_way_partition(void)
+{
+ return cvmx_read_csr(CVMX_L2C_SPAR4) & (0xFF);
+}
+
+void cvmx_l2c_config_perf(uint32_t counter, enum cvmx_l2c_event event,
+ uint32_t clear_on_read)
+{
+ union cvmx_l2c_pfctl pfctl;
+
+ pfctl.u64 = cvmx_read_csr(CVMX_L2C_PFCTL);
+
+ switch (counter) {
+ case 0:
+ pfctl.s.cnt0sel = event;
+ pfctl.s.cnt0ena = 1;
+ if (!cvmx_octeon_is_pass1())
+ pfctl.s.cnt0rdclr = clear_on_read;
+ break;
+ case 1:
+ pfctl.s.cnt1sel = event;
+ pfctl.s.cnt1ena = 1;
+ if (!cvmx_octeon_is_pass1())
+ pfctl.s.cnt1rdclr = clear_on_read;
+ break;
+ case 2:
+ pfctl.s.cnt2sel = event;
+ pfctl.s.cnt2ena = 1;
+ if (!cvmx_octeon_is_pass1())
+ pfctl.s.cnt2rdclr = clear_on_read;
+ break;
+ case 3:
+ default:
+ pfctl.s.cnt3sel = event;
+ pfctl.s.cnt3ena = 1;
+ if (!cvmx_octeon_is_pass1())
+ pfctl.s.cnt3rdclr = clear_on_read;
+ break;
+ }
+
+ cvmx_write_csr(CVMX_L2C_PFCTL, pfctl.u64);
+}
+
+uint64_t cvmx_l2c_read_perf(uint32_t counter)
+{
+ switch (counter) {
+ case 0:
+ return cvmx_read_csr(CVMX_L2C_PFC0);
+ case 1:
+ return cvmx_read_csr(CVMX_L2C_PFC1);
+ case 2:
+ return cvmx_read_csr(CVMX_L2C_PFC2);
+ case 3:
+ default:
+ return cvmx_read_csr(CVMX_L2C_PFC3);
+ }
+}
+
+/**
+ * @INTERNAL
+ * Helper function use to fault in cache lines for L2 cache locking
+ *
+ * @addr: Address of base of memory region to read into L2 cache
+ * @len: Length (in bytes) of region to fault in
+ */
+static void fault_in(uint64_t addr, int len)
+{
+ volatile char *ptr;
+ volatile char dummy;
+ /*
+ * Adjust addr and length so we get all cache lines even for
+ * small ranges spanning two cache lines
+ */
+ len += addr & CVMX_CACHE_LINE_MASK;
+ addr &= ~CVMX_CACHE_LINE_MASK;
+ ptr = (volatile char *)cvmx_phys_to_ptr(addr);
+ /*
+ * Invalidate L1 cache to make sure all loads result in data
+ * being in L2.
+ */
+ CVMX_DCACHE_INVALIDATE;
+ while (len > 0) {
+ dummy += *ptr;
+ len -= CVMX_CACHE_LINE_SIZE;
+ ptr += CVMX_CACHE_LINE_SIZE;
+ }
+}
+
+int cvmx_l2c_lock_line(uint64_t addr)
+{
+ int retval = 0;
+ union cvmx_l2c_dbg l2cdbg;
+ union cvmx_l2c_lckbase lckbase;
+ union cvmx_l2c_lckoff lckoff;
+ union cvmx_l2t_err l2t_err;
+ l2cdbg.u64 = 0;
+ lckbase.u64 = 0;
+ lckoff.u64 = 0;
+
+ cvmx_spinlock_lock(&cvmx_l2c_spinlock);
+
+ /* Clear l2t error bits if set */
+ l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
+ l2t_err.s.lckerr = 1;
+ l2t_err.s.lckerr2 = 1;
+ cvmx_write_csr(CVMX_L2T_ERR, l2t_err.u64);
+
+ addr &= ~CVMX_CACHE_LINE_MASK;
+
+ /* Set this core as debug core */
+ l2cdbg.s.ppnum = cvmx_get_core_num();
+ CVMX_SYNC;
+ cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
+ cvmx_read_csr(CVMX_L2C_DBG);
+
+ lckoff.s.lck_offset = 0; /* Only lock 1 line at a time */
+ cvmx_write_csr(CVMX_L2C_LCKOFF, lckoff.u64);
+ cvmx_read_csr(CVMX_L2C_LCKOFF);
+
+ if (((union cvmx_l2c_cfg) (cvmx_read_csr(CVMX_L2C_CFG))).s.idxalias) {
+ int alias_shift =
+ CVMX_L2C_IDX_ADDR_SHIFT + 2 * CVMX_L2_SET_BITS - 1;
+ uint64_t addr_tmp =
+ addr ^ (addr & ((1 << alias_shift) - 1)) >>
+ CVMX_L2_SET_BITS;
+ lckbase.s.lck_base = addr_tmp >> 7;
+ } else {
+ lckbase.s.lck_base = addr >> 7;
+ }
+
+ lckbase.s.lck_ena = 1;
+ cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64);
+ cvmx_read_csr(CVMX_L2C_LCKBASE); /* Make sure it gets there */
+
+ fault_in(addr, CVMX_CACHE_LINE_SIZE);
+
+ lckbase.s.lck_ena = 0;
+ cvmx_write_csr(CVMX_L2C_LCKBASE, lckbase.u64);
+ cvmx_read_csr(CVMX_L2C_LCKBASE); /* Make sure it gets there */
+
+ /* Stop being debug core */
+ cvmx_write_csr(CVMX_L2C_DBG, 0);
+ cvmx_read_csr(CVMX_L2C_DBG);
+
+ l2t_err.u64 = cvmx_read_csr(CVMX_L2T_ERR);
+ if (l2t_err.s.lckerr || l2t_err.s.lckerr2)
+ retval = 1; /* We were unable to lock the line */
+
+ cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
+
+ return retval;
+}
+
+int cvmx_l2c_lock_mem_region(uint64_t start, uint64_t len)
+{
+ int retval = 0;
+
+ /* Round start/end to cache line boundaries */
+ len += start & CVMX_CACHE_LINE_MASK;
+ start &= ~CVMX_CACHE_LINE_MASK;
+ len = (len + CVMX_CACHE_LINE_MASK) & ~CVMX_CACHE_LINE_MASK;
+
+ while (len) {
+ retval += cvmx_l2c_lock_line(start);
+ start += CVMX_CACHE_LINE_SIZE;
+ len -= CVMX_CACHE_LINE_SIZE;
+ }
+
+ return retval;
+}
+
+void cvmx_l2c_flush(void)
+{
+ uint64_t assoc, set;
+ uint64_t n_assoc, n_set;
+ union cvmx_l2c_dbg l2cdbg;
+
+ cvmx_spinlock_lock(&cvmx_l2c_spinlock);
+
+ l2cdbg.u64 = 0;
+ if (!OCTEON_IS_MODEL(OCTEON_CN30XX))
+ l2cdbg.s.ppnum = cvmx_get_core_num();
+ l2cdbg.s.finv = 1;
+ n_set = CVMX_L2_SETS;
+ n_assoc = l2_size_half() ? (CVMX_L2_ASSOC / 2) : CVMX_L2_ASSOC;
+ for (set = 0; set < n_set; set++) {
+ for (assoc = 0; assoc < n_assoc; assoc++) {
+ l2cdbg.s.set = assoc;
+ /* Enter debug mode, and make sure all other
+ ** writes complete before we enter debug
+ ** mode */
+ CVMX_SYNCW;
+ cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
+ cvmx_read_csr(CVMX_L2C_DBG);
+
+ CVMX_PREPARE_FOR_STORE(CVMX_ADD_SEG
+ (CVMX_MIPS_SPACE_XKPHYS,
+ set * CVMX_CACHE_LINE_SIZE), 0);
+ CVMX_SYNCW; /* Push STF out to L2 */
+ /* Exit debug mode */
+ CVMX_SYNC;
+ cvmx_write_csr(CVMX_L2C_DBG, 0);
+ cvmx_read_csr(CVMX_L2C_DBG);
+ }
+ }
+
+ cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
+}
+
+int cvmx_l2c_unlock_line(uint64_t address)
+{
+ int assoc;
+ union cvmx_l2c_tag tag;
+ union cvmx_l2c_dbg l2cdbg;
+ uint32_t tag_addr;
+
+ uint32_t index = cvmx_l2c_address_to_index(address);
+
+ cvmx_spinlock_lock(&cvmx_l2c_spinlock);
+ /* Compute portion of address that is stored in tag */
+ tag_addr =
+ ((address >> CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) &
+ ((1 << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT) - 1));
+ for (assoc = 0; assoc < CVMX_L2_ASSOC; assoc++) {
+ tag = cvmx_get_l2c_tag(assoc, index);
+
+ if (tag.s.V && (tag.s.addr == tag_addr)) {
+ l2cdbg.u64 = 0;
+ l2cdbg.s.ppnum = cvmx_get_core_num();
+ l2cdbg.s.set = assoc;
+ l2cdbg.s.finv = 1;
+
+ CVMX_SYNC;
+ /* Enter debug mode */
+ cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
+ cvmx_read_csr(CVMX_L2C_DBG);
+
+ CVMX_PREPARE_FOR_STORE(CVMX_ADD_SEG
+ (CVMX_MIPS_SPACE_XKPHYS,
+ address), 0);
+ CVMX_SYNC;
+ /* Exit debug mode */
+ cvmx_write_csr(CVMX_L2C_DBG, 0);
+ cvmx_read_csr(CVMX_L2C_DBG);
+ cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
+ return tag.s.L;
+ }
+ }
+ cvmx_spinlock_unlock(&cvmx_l2c_spinlock);
+ return 0;
+}
+
+int cvmx_l2c_unlock_mem_region(uint64_t start, uint64_t len)
+{
+ int num_unlocked = 0;
+ /* Round start/end to cache line boundaries */
+ len += start & CVMX_CACHE_LINE_MASK;
+ start &= ~CVMX_CACHE_LINE_MASK;
+ len = (len + CVMX_CACHE_LINE_MASK) & ~CVMX_CACHE_LINE_MASK;
+ while (len > 0) {
+ num_unlocked += cvmx_l2c_unlock_line(start);
+ start += CVMX_CACHE_LINE_SIZE;
+ len -= CVMX_CACHE_LINE_SIZE;
+ }
+
+ return num_unlocked;
+}
+
+/*
+ * Internal l2c tag types. These are converted to a generic structure
+ * that can be used on all chips.
+ */
+union __cvmx_l2c_tag {
+ uint64_t u64;
+ struct cvmx_l2c_tag_cn50xx {
+ uint64_t reserved:40;
+ uint64_t V:1; /* Line valid */
+ uint64_t D:1; /* Line dirty */
+ uint64_t L:1; /* Line locked */
+ uint64_t U:1; /* Use, LRU eviction */
+ uint64_t addr:20; /* Phys mem addr (33..14) */
+ } cn50xx;
+ struct cvmx_l2c_tag_cn30xx {
+ uint64_t reserved:41;
+ uint64_t V:1; /* Line valid */
+ uint64_t D:1; /* Line dirty */
+ uint64_t L:1; /* Line locked */
+ uint64_t U:1; /* Use, LRU eviction */
+ uint64_t addr:19; /* Phys mem addr (33..15) */
+ } cn30xx;
+ struct cvmx_l2c_tag_cn31xx {
+ uint64_t reserved:42;
+ uint64_t V:1; /* Line valid */
+ uint64_t D:1; /* Line dirty */
+ uint64_t L:1; /* Line locked */
+ uint64_t U:1; /* Use, LRU eviction */
+ uint64_t addr:18; /* Phys mem addr (33..16) */
+ } cn31xx;
+ struct cvmx_l2c_tag_cn38xx {
+ uint64_t reserved:43;
+ uint64_t V:1; /* Line valid */
+ uint64_t D:1; /* Line dirty */
+ uint64_t L:1; /* Line locked */
+ uint64_t U:1; /* Use, LRU eviction */
+ uint64_t addr:17; /* Phys mem addr (33..17) */
+ } cn38xx;
+ struct cvmx_l2c_tag_cn58xx {
+ uint64_t reserved:44;
+ uint64_t V:1; /* Line valid */
+ uint64_t D:1; /* Line dirty */
+ uint64_t L:1; /* Line locked */
+ uint64_t U:1; /* Use, LRU eviction */
+ uint64_t addr:16; /* Phys mem addr (33..18) */
+ } cn58xx;
+ struct cvmx_l2c_tag_cn58xx cn56xx; /* 2048 sets */
+ struct cvmx_l2c_tag_cn31xx cn52xx; /* 512 sets */
+};
+
+/**
+ * @INTERNAL
+ * Function to read a L2C tag. This code make the current core
+ * the 'debug core' for the L2. This code must only be executed by
+ * 1 core at a time.
+ *
+ * @assoc: Association (way) of the tag to dump
+ * @index: Index of the cacheline
+ *
+ * Returns The Octeon model specific tag structure. This is
+ * translated by a wrapper function to a generic form that is
+ * easier for applications to use.
+ */
+static union __cvmx_l2c_tag __read_l2_tag(uint64_t assoc, uint64_t index)
+{
+
+ uint64_t debug_tag_addr = (((1ULL << 63) | (index << 7)) + 96);
+ uint64_t core = cvmx_get_core_num();
+ union __cvmx_l2c_tag tag_val;
+ uint64_t dbg_addr = CVMX_L2C_DBG;
+ unsigned long flags;
+
+ union cvmx_l2c_dbg debug_val;
+ debug_val.u64 = 0;
+ /*
+ * For low core count parts, the core number is always small enough
+ * to stay in the correct field and not set any reserved bits.
+ */
+ debug_val.s.ppnum = core;
+ debug_val.s.l2t = 1;
+ debug_val.s.set = assoc;
+ /*
+ * Make sure core is quiet (no prefetches, etc.) before
+ * entering debug mode.
+ */
+ CVMX_SYNC;
+ /* Flush L1 to make sure debug load misses L1 */
+ CVMX_DCACHE_INVALIDATE;
+
+ local_irq_save(flags);
+
+ /*
+ * The following must be done in assembly as when in debug
+ * mode all data loads from L2 return special debug data, not
+ * normal memory contents. Also, interrupts must be
+ * disabled, since if an interrupt occurs while in debug mode
+ * the ISR will get debug data from all its memory reads
+ * instead of the contents of memory
+ */
+
+ asm volatile (".set push \n"
+ " .set mips64 \n"
+ " .set noreorder \n"
+ /* Enter debug mode, wait for store */
+ " sd %[dbg_val], 0(%[dbg_addr]) \n"
+ " ld $0, 0(%[dbg_addr]) \n"
+ /* Read L2C tag data */
+ " ld %[tag_val], 0(%[tag_addr]) \n"
+ /* Exit debug mode, wait for store */
+ " sd $0, 0(%[dbg_addr]) \n"
+ " ld $0, 0(%[dbg_addr]) \n"
+ /* Invalidate dcache to discard debug data */
+ " cache 9, 0($0) \n"
+ " .set pop" :
+ [tag_val] "=r"(tag_val.u64) : [dbg_addr] "r"(dbg_addr),
+ [dbg_val] "r"(debug_val.u64),
+ [tag_addr] "r"(debug_tag_addr) : "memory");
+
+ local_irq_restore(flags);
+ return tag_val;
+
+}
+
+union cvmx_l2c_tag cvmx_l2c_get_tag(uint32_t association, uint32_t index)
+{
+ union __cvmx_l2c_tag tmp_tag;
+ union cvmx_l2c_tag tag;
+ tag.u64 = 0;
+
+ if ((int)association >= cvmx_l2c_get_num_assoc()) {
+ cvmx_dprintf
+ ("ERROR: cvmx_get_l2c_tag association out of range\n");
+ return tag;
+ }
+ if ((int)index >= cvmx_l2c_get_num_sets()) {
+ cvmx_dprintf("ERROR: cvmx_get_l2c_tag "
+ "index out of range (arg: %d, max: %d\n",
+ index, cvmx_l2c_get_num_sets());
+ return tag;
+ }
+ /* __read_l2_tag is intended for internal use only */
+ tmp_tag = __read_l2_tag(association, index);
+
+ /*
+ * Convert all tag structure types to generic version, as it
+ * can represent all models.
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN58XX) || OCTEON_IS_MODEL(OCTEON_CN56XX)) {
+ tag.s.V = tmp_tag.cn58xx.V;
+ tag.s.D = tmp_tag.cn58xx.D;
+ tag.s.L = tmp_tag.cn58xx.L;
+ tag.s.U = tmp_tag.cn58xx.U;
+ tag.s.addr = tmp_tag.cn58xx.addr;
+ } else if (OCTEON_IS_MODEL(OCTEON_CN38XX)) {
+ tag.s.V = tmp_tag.cn38xx.V;
+ tag.s.D = tmp_tag.cn38xx.D;
+ tag.s.L = tmp_tag.cn38xx.L;
+ tag.s.U = tmp_tag.cn38xx.U;
+ tag.s.addr = tmp_tag.cn38xx.addr;
+ } else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
+ || OCTEON_IS_MODEL(OCTEON_CN52XX)) {
+ tag.s.V = tmp_tag.cn31xx.V;
+ tag.s.D = tmp_tag.cn31xx.D;
+ tag.s.L = tmp_tag.cn31xx.L;
+ tag.s.U = tmp_tag.cn31xx.U;
+ tag.s.addr = tmp_tag.cn31xx.addr;
+ } else if (OCTEON_IS_MODEL(OCTEON_CN30XX)) {
+ tag.s.V = tmp_tag.cn30xx.V;
+ tag.s.D = tmp_tag.cn30xx.D;
+ tag.s.L = tmp_tag.cn30xx.L;
+ tag.s.U = tmp_tag.cn30xx.U;
+ tag.s.addr = tmp_tag.cn30xx.addr;
+ } else if (OCTEON_IS_MODEL(OCTEON_CN50XX)) {
+ tag.s.V = tmp_tag.cn50xx.V;
+ tag.s.D = tmp_tag.cn50xx.D;
+ tag.s.L = tmp_tag.cn50xx.L;
+ tag.s.U = tmp_tag.cn50xx.U;
+ tag.s.addr = tmp_tag.cn50xx.addr;
+ } else {
+ cvmx_dprintf("Unsupported OCTEON Model in %s\n", __func__);
+ }
+
+ return tag;
+}
+
+uint32_t cvmx_l2c_address_to_index(uint64_t addr)
+{
+ uint64_t idx = addr >> CVMX_L2C_IDX_ADDR_SHIFT;
+ union cvmx_l2c_cfg l2c_cfg;
+ l2c_cfg.u64 = cvmx_read_csr(CVMX_L2C_CFG);
+
+ if (l2c_cfg.s.idxalias) {
+ idx ^=
+ ((addr & CVMX_L2C_ALIAS_MASK) >>
+ CVMX_L2C_TAG_ADDR_ALIAS_SHIFT);
+ }
+ idx &= CVMX_L2C_IDX_MASK;
+ return idx;
+}
+
+int cvmx_l2c_get_cache_size_bytes(void)
+{
+ return cvmx_l2c_get_num_sets() * cvmx_l2c_get_num_assoc() *
+ CVMX_CACHE_LINE_SIZE;
+}
+
+/**
+ * Return log base 2 of the number of sets in the L2 cache
+ * Returns
+ */
+int cvmx_l2c_get_set_bits(void)
+{
+ int l2_set_bits;
+ if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN58XX))
+ l2_set_bits = 11; /* 2048 sets */
+ else if (OCTEON_IS_MODEL(OCTEON_CN38XX))
+ l2_set_bits = 10; /* 1024 sets */
+ else if (OCTEON_IS_MODEL(OCTEON_CN31XX)
+ || OCTEON_IS_MODEL(OCTEON_CN52XX))
+ l2_set_bits = 9; /* 512 sets */
+ else if (OCTEON_IS_MODEL(OCTEON_CN30XX))
+ l2_set_bits = 8; /* 256 sets */
+ else if (OCTEON_IS_MODEL(OCTEON_CN50XX))
+ l2_set_bits = 7; /* 128 sets */
+ else {
+ cvmx_dprintf("Unsupported OCTEON Model in %s\n", __func__);
+ l2_set_bits = 11; /* 2048 sets */
+ }
+ return l2_set_bits;
+
+}
+
+/* Return the number of sets in the L2 Cache */
+int cvmx_l2c_get_num_sets(void)
+{
+ return 1 << cvmx_l2c_get_set_bits();
+}
+
+/* Return the number of associations in the L2 Cache */
+int cvmx_l2c_get_num_assoc(void)
+{
+ int l2_assoc;
+ if (OCTEON_IS_MODEL(OCTEON_CN56XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN52XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN58XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN50XX) || OCTEON_IS_MODEL(OCTEON_CN38XX))
+ l2_assoc = 8;
+ else if (OCTEON_IS_MODEL(OCTEON_CN31XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN30XX))
+ l2_assoc = 4;
+ else {
+ cvmx_dprintf("Unsupported OCTEON Model in %s\n", __func__);
+ l2_assoc = 8;
+ }
+
+ /* Check to see if part of the cache is disabled */
+ if (cvmx_fuse_read(265))
+ l2_assoc = l2_assoc >> 2;
+ else if (cvmx_fuse_read(264))
+ l2_assoc = l2_assoc >> 1;
+
+ return l2_assoc;
+}
+
+/**
+ * Flush a line from the L2 cache
+ * This should only be called from one core at a time, as this routine
+ * sets the core to the 'debug' core in order to flush the line.
+ *
+ * @assoc: Association (or way) to flush
+ * @index: Index to flush
+ */
+void cvmx_l2c_flush_line(uint32_t assoc, uint32_t index)
+{
+ union cvmx_l2c_dbg l2cdbg;
+
+ l2cdbg.u64 = 0;
+ l2cdbg.s.ppnum = cvmx_get_core_num();
+ l2cdbg.s.finv = 1;
+
+ l2cdbg.s.set = assoc;
+ /*
+ * Enter debug mode, and make sure all other writes complete
+ * before we enter debug mode.
+ */
+ asm volatile ("sync" : : : "memory");
+ cvmx_write_csr(CVMX_L2C_DBG, l2cdbg.u64);
+ cvmx_read_csr(CVMX_L2C_DBG);
+
+ CVMX_PREPARE_FOR_STORE(((1ULL << 63) + (index) * 128), 0);
+ /* Exit debug mode */
+ asm volatile ("sync" : : : "memory");
+ cvmx_write_csr(CVMX_L2C_DBG, 0);
+ cvmx_read_csr(CVMX_L2C_DBG);
+}
diff --git a/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c b/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c
new file mode 100644
index 0000000..48123707
--- /dev/null
+++ b/arch/mips/cavium-octeon/executive/cvmx-sysinfo.c
@@ -0,0 +1,116 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * This module provides system/board/application information obtained
+ * by the bootloader.
+ */
+
+#include <asm/octeon/cvmx.h>
+#include <asm/octeon/cvmx-spinlock.h>
+#include <asm/octeon/cvmx-sysinfo.h>
+
+/**
+ * This structure defines the private state maintained by sysinfo module.
+ *
+ */
+static struct {
+ struct cvmx_sysinfo sysinfo; /* system information */
+ cvmx_spinlock_t lock; /* mutex spinlock */
+
+} state = {
+ .lock = CVMX_SPINLOCK_UNLOCKED_INITIALIZER
+};
+
+
+/*
+ * Global variables that define the min/max of the memory region set
+ * up for 32 bit userspace access.
+ */
+uint64_t linux_mem32_min;
+uint64_t linux_mem32_max;
+uint64_t linux_mem32_wired;
+uint64_t linux_mem32_offset;
+
+/**
+ * This function returns the application information as obtained
+ * by the bootloader. This provides the core mask of the cores
+ * running the same application image, as well as the physical
+ * memory regions available to the core.
+ *
+ * Returns Pointer to the boot information structure
+ *
+ */
+struct cvmx_sysinfo *cvmx_sysinfo_get(void)
+{
+ return &(state.sysinfo);
+}
+
+/**
+ * This function is used in non-simple executive environments (such as
+ * Linux kernel, u-boot, etc.) to configure the minimal fields that
+ * are required to use simple executive files directly.
+ *
+ * Locking (if required) must be handled outside of this
+ * function
+ *
+ * @phy_mem_desc_ptr:
+ * Pointer to global physical memory descriptor
+ * (bootmem descriptor) @board_type: Octeon board
+ * type enumeration
+ *
+ * @board_rev_major:
+ * Board major revision
+ * @board_rev_minor:
+ * Board minor revision
+ * @cpu_clock_hz:
+ * CPU clock freqency in hertz
+ *
+ * Returns 0: Failure
+ * 1: success
+ */
+int cvmx_sysinfo_minimal_initialize(void *phy_mem_desc_ptr,
+ uint16_t board_type,
+ uint8_t board_rev_major,
+ uint8_t board_rev_minor,
+ uint32_t cpu_clock_hz)
+{
+
+ /* The sysinfo structure was already initialized */
+ if (state.sysinfo.board_type)
+ return 0;
+
+ memset(&(state.sysinfo), 0x0, sizeof(state.sysinfo));
+ state.sysinfo.phy_mem_desc_ptr = phy_mem_desc_ptr;
+ state.sysinfo.board_type = board_type;
+ state.sysinfo.board_rev_major = board_rev_major;
+ state.sysinfo.board_rev_minor = board_rev_minor;
+ state.sysinfo.cpu_clock_hz = cpu_clock_hz;
+
+ return 1;
+}
+
diff --git a/arch/mips/cavium-octeon/executive/octeon-model.c b/arch/mips/cavium-octeon/executive/octeon-model.c
new file mode 100644
index 0000000..9afc379
--- /dev/null
+++ b/arch/mips/cavium-octeon/executive/octeon-model.c
@@ -0,0 +1,358 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * File defining functions for working with different Octeon
+ * models.
+ */
+#include <asm/octeon/octeon.h>
+
+/**
+ * Given the chip processor ID from COP0, this function returns a
+ * string representing the chip model number. The string is of the
+ * form CNXXXXpX.X-FREQ-SUFFIX.
+ * - XXXX = The chip model number
+ * - X.X = Chip pass number
+ * - FREQ = Current frequency in Mhz
+ * - SUFFIX = NSP, EXP, SCP, SSP, or CP
+ *
+ * @chip_id: Chip ID
+ *
+ * Returns Model string
+ */
+const char *octeon_model_get_string(uint32_t chip_id)
+{
+ static char buffer[32];
+ return octeon_model_get_string_buffer(chip_id, buffer);
+}
+
+/*
+ * Version of octeon_model_get_string() that takes buffer as argument,
+ * as running early in u-boot static/global variables don't work when
+ * running from flash.
+ */
+const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer)
+{
+ const char *family;
+ const char *core_model;
+ char pass[4];
+ int clock_mhz;
+ const char *suffix;
+ union cvmx_l2d_fus3 fus3;
+ int num_cores;
+ union cvmx_mio_fus_dat2 fus_dat2;
+ union cvmx_mio_fus_dat3 fus_dat3;
+ char fuse_model[10];
+ uint32_t fuse_data = 0;
+
+ fus3.u64 = cvmx_read_csr(CVMX_L2D_FUS3);
+ fus_dat2.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT2);
+ fus_dat3.u64 = cvmx_read_csr(CVMX_MIO_FUS_DAT3);
+
+ num_cores = cvmx_octeon_num_cores();
+
+ /* Make sure the non existant devices look disabled */
+ switch ((chip_id >> 8) & 0xff) {
+ case 6: /* CN50XX */
+ case 2: /* CN30XX */
+ fus_dat3.s.nodfa_dte = 1;
+ fus_dat3.s.nozip = 1;
+ break;
+ case 4: /* CN57XX or CN56XX */
+ fus_dat3.s.nodfa_dte = 1;
+ break;
+ default:
+ break;
+ }
+
+ /* Make a guess at the suffix */
+ /* NSP = everything */
+ /* EXP = No crypto */
+ /* SCP = No DFA, No zip */
+ /* CP = No DFA, No crypto, No zip */
+ if (fus_dat3.s.nodfa_dte) {
+ if (fus_dat2.s.nocrypto)
+ suffix = "CP";
+ else
+ suffix = "SCP";
+ } else if (fus_dat2.s.nocrypto)
+ suffix = "EXP";
+ else
+ suffix = "NSP";
+
+ /*
+ * Assume pass number is encoded using <5:3><2:0>. Exceptions
+ * will be fixed later.
+ */
+ sprintf(pass, "%u.%u", ((chip_id >> 3) & 7) + 1, chip_id & 7);
+
+ /*
+ * Use the number of cores to determine the last 2 digits of
+ * the model number. There are some exceptions that are fixed
+ * later.
+ */
+ switch (num_cores) {
+ case 16:
+ core_model = "60";
+ break;
+ case 15:
+ core_model = "58";
+ break;
+ case 14:
+ core_model = "55";
+ break;
+ case 13:
+ core_model = "52";
+ break;
+ case 12:
+ core_model = "50";
+ break;
+ case 11:
+ core_model = "48";
+ break;
+ case 10:
+ core_model = "45";
+ break;
+ case 9:
+ core_model = "42";
+ break;
+ case 8:
+ core_model = "40";
+ break;
+ case 7:
+ core_model = "38";
+ break;
+ case 6:
+ core_model = "34";
+ break;
+ case 5:
+ core_model = "32";
+ break;
+ case 4:
+ core_model = "30";
+ break;
+ case 3:
+ core_model = "25";
+ break;
+ case 2:
+ core_model = "20";
+ break;
+ case 1:
+ core_model = "10";
+ break;
+ default:
+ core_model = "XX";
+ break;
+ }
+
+ /* Now figure out the family, the first two digits */
+ switch ((chip_id >> 8) & 0xff) {
+ case 0: /* CN38XX, CN37XX or CN36XX */
+ if (fus3.cn38xx.crip_512k) {
+ /*
+ * For some unknown reason, the 16 core one is
+ * called 37 instead of 36.
+ */
+ if (num_cores >= 16)
+ family = "37";
+ else
+ family = "36";
+ } else
+ family = "38";
+ /*
+ * This series of chips didn't follow the standard
+ * pass numbering.
+ */
+ switch (chip_id & 0xf) {
+ case 0:
+ strcpy(pass, "1.X");
+ break;
+ case 1:
+ strcpy(pass, "2.X");
+ break;
+ case 3:
+ strcpy(pass, "3.X");
+ break;
+ default:
+ strcpy(pass, "X.X");
+ break;
+ }
+ break;
+ case 1: /* CN31XX or CN3020 */
+ if ((chip_id & 0x10) || fus3.cn31xx.crip_128k)
+ family = "30";
+ else
+ family = "31";
+ /*
+ * This series of chips didn't follow the standard
+ * pass numbering.
+ */
+ switch (chip_id & 0xf) {
+ case 0:
+ strcpy(pass, "1.0");
+ break;
+ case 2:
+ strcpy(pass, "1.1");
+ break;
+ default:
+ strcpy(pass, "X.X");
+ break;
+ }
+ break;
+ case 2: /* CN3010 or CN3005 */
+ family = "30";
+ /* A chip with half cache is an 05 */
+ if (fus3.cn30xx.crip_64k)
+ core_model = "05";
+ /*
+ * This series of chips didn't follow the standard
+ * pass numbering.
+ */
+ switch (chip_id & 0xf) {
+ case 0:
+ strcpy(pass, "1.0");
+ break;
+ case 2:
+ strcpy(pass, "1.1");
+ break;
+ default:
+ strcpy(pass, "X.X");
+ break;
+ }
+ break;
+ case 3: /* CN58XX */
+ family = "58";
+ /* Special case. 4 core, no crypto */
+ if ((num_cores == 4) && fus_dat2.cn38xx.nocrypto)
+ core_model = "29";
+
+ /* Pass 1 uses different encodings for pass numbers */
+ if ((chip_id & 0xFF) < 0x8) {
+ switch (chip_id & 0x3) {
+ case 0:
+ strcpy(pass, "1.0");
+ break;
+ case 1:
+ strcpy(pass, "1.1");
+ break;
+ case 3:
+ strcpy(pass, "1.2");
+ break;
+ default:
+ strcpy(pass, "1.X");
+ break;
+ }
+ }
+ break;
+ case 4: /* CN57XX, CN56XX, CN55XX, CN54XX */
+ if (fus_dat2.cn56xx.raid_en) {
+ if (fus3.cn56xx.crip_1024k)
+ family = "55";
+ else
+ family = "57";
+ if (fus_dat2.cn56xx.nocrypto)
+ suffix = "SP";
+ else
+ suffix = "SSP";
+ } else {
+ if (fus_dat2.cn56xx.nocrypto)
+ suffix = "CP";
+ else {
+ suffix = "NSP";
+ if (fus_dat3.s.nozip)
+ suffix = "SCP";
+ }
+ if (fus3.cn56xx.crip_1024k)
+ family = "54";
+ else
+ family = "56";
+ }
+ break;
+ case 6: /* CN50XX */
+ family = "50";
+ break;
+ case 7: /* CN52XX */
+ if (fus3.cn52xx.crip_256k)
+ family = "51";
+ else
+ family = "52";
+ break;
+ default:
+ family = "XX";
+ core_model = "XX";
+ strcpy(pass, "X.X");
+ suffix = "XXX";
+ break;
+ }
+
+ clock_mhz = octeon_get_clock_rate() / 1000000;
+
+ if (family[0] != '3') {
+ /* Check for model in fuses, overrides normal decode */
+ /* This is _not_ valid for Octeon CN3XXX models */
+ fuse_data |= cvmx_fuse_read_byte(51);
+ fuse_data = fuse_data << 8;
+ fuse_data |= cvmx_fuse_read_byte(50);
+ fuse_data = fuse_data << 8;
+ fuse_data |= cvmx_fuse_read_byte(49);
+ fuse_data = fuse_data << 8;
+ fuse_data |= cvmx_fuse_read_byte(48);
+ if (fuse_data & 0x7ffff) {
+ int model = fuse_data & 0x3fff;
+ int suffix = (fuse_data >> 14) & 0x1f;
+ if (suffix && model) {
+ /*
+ * Have both number and suffix in
+ * fuses, so both
+ */
+ sprintf(fuse_model, "%d%c",
+ model, 'A' + suffix - 1);
+ core_model = "";
+ family = fuse_model;
+ } else if (suffix && !model) {
+ /*
+ * Only have suffix, so add suffix to
+ * 'normal' model number.
+ */
+ sprintf(fuse_model, "%s%c", core_model,
+ 'A' + suffix - 1);
+ core_model = fuse_model;
+ } else {
+ /*
+ * Don't have suffix, so just use
+ * model from fuses.
+ */
+ sprintf(fuse_model, "%d", model);
+ core_model = "";
+ family = fuse_model;
+ }
+ }
+ }
+ sprintf(buffer, "CN%s%sp%s-%d-%s",
+ family, core_model, pass, clock_mhz, suffix);
+ return buffer;
+}
diff --git a/arch/mips/cavium-octeon/flash_setup.c b/arch/mips/cavium-octeon/flash_setup.c
new file mode 100644
index 0000000..553d36c
--- /dev/null
+++ b/arch/mips/cavium-octeon/flash_setup.c
@@ -0,0 +1,84 @@
+/*
+ * Octeon Bootbus flash setup
+ *
+ * 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) 2007, 2008 Cavium Networks
+ */
+#include <linux/kernel.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/octeon/octeon.h>
+
+static struct map_info flash_map;
+static struct mtd_info *mymtd;
+#ifdef CONFIG_MTD_PARTITIONS
+static int nr_parts;
+static struct mtd_partition *parts;
+static const char *part_probe_types[] = {
+ "cmdlinepart",
+#ifdef CONFIG_MTD_REDBOOT_PARTS
+ "RedBoot",
+#endif
+ NULL
+};
+#endif
+
+/**
+ * Module/ driver initialization.
+ *
+ * Returns Zero on success
+ */
+static int __init flash_init(void)
+{
+ /*
+ * Read the bootbus region 0 setup to determine the base
+ * address of the flash.
+ */
+ union cvmx_mio_boot_reg_cfgx region_cfg;
+ region_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(0));
+ if (region_cfg.s.en) {
+ /*
+ * The bootloader always takes the flash and sets its
+ * address so the entire flash fits below
+ * 0x1fc00000. This way the flash aliases to
+ * 0x1fc00000 for booting. Software can access the
+ * full flash at the true address, while core boot can
+ * access 4MB.
+ */
+ /* Use this name so old part lines work */
+ flash_map.name = "phys_mapped_flash";
+ flash_map.phys = region_cfg.s.base << 16;
+ flash_map.size = 0x1fc00000 - flash_map.phys;
+ flash_map.bankwidth = 1;
+ flash_map.virt = ioremap(flash_map.phys, flash_map.size);
+ pr_notice("Bootbus flash: Setting flash for %luMB flash at "
+ "0x%08lx\n", flash_map.size >> 20, flash_map.phys);
+ simple_map_init(&flash_map);
+ mymtd = do_map_probe("cfi_probe", &flash_map);
+ if (mymtd) {
+ mymtd->owner = THIS_MODULE;
+
+#ifdef CONFIG_MTD_PARTITIONS
+ nr_parts = parse_mtd_partitions(mymtd,
+ part_probe_types,
+ &parts, 0);
+ if (nr_parts > 0)
+ add_mtd_partitions(mymtd, parts, nr_parts);
+ else
+ add_mtd_device(mymtd);
+#else
+ add_mtd_device(mymtd);
+#endif
+ } else {
+ pr_err("Failed to register MTD device for flash\n");
+ }
+ }
+ return 0;
+}
+
+late_initcall(flash_init);
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
new file mode 100644
index 0000000..fc72984
--- /dev/null
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -0,0 +1,497 @@
+/*
+ * 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-2008 Cavium Networks
+ */
+#include <linux/irq.h>
+#include <linux/interrupt.h>
+#include <linux/hardirq.h>
+
+#include <asm/octeon/octeon.h>
+
+DEFINE_RWLOCK(octeon_irq_ciu0_rwlock);
+DEFINE_RWLOCK(octeon_irq_ciu1_rwlock);
+DEFINE_SPINLOCK(octeon_irq_msi_lock);
+
+static void octeon_irq_core_ack(unsigned int irq)
+{
+ unsigned int bit = irq - OCTEON_IRQ_SW0;
+ /*
+ * We don't need to disable IRQs to make these atomic since
+ * they are already disabled earlier in the low level
+ * interrupt code.
+ */
+ clear_c0_status(0x100 << bit);
+ /* The two user interrupts must be cleared manually. */
+ if (bit < 2)
+ clear_c0_cause(0x100 << bit);
+}
+
+static void octeon_irq_core_eoi(unsigned int irq)
+{
+ irq_desc_t *desc = irq_desc + irq;
+ unsigned int bit = irq - OCTEON_IRQ_SW0;
+ /*
+ * If an IRQ is being processed while we are disabling it the
+ * handler will attempt to unmask the interrupt after it has
+ * been disabled.
+ */
+ if (desc->status & IRQ_DISABLED)
+ return;
+
+ /* There is a race here. We should fix it. */
+
+ /*
+ * We don't need to disable IRQs to make these atomic since
+ * they are already disabled earlier in the low level
+ * interrupt code.
+ */
+ set_c0_status(0x100 << bit);
+}
+
+static void octeon_irq_core_enable(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned int bit = irq - OCTEON_IRQ_SW0;
+
+ /*
+ * We need to disable interrupts to make sure our updates are
+ * atomic.
+ */
+ local_irq_save(flags);
+ set_c0_status(0x100 << bit);
+ local_irq_restore(flags);
+}
+
+static void octeon_irq_core_disable_local(unsigned int irq)
+{
+ unsigned long flags;
+ unsigned int bit = irq - OCTEON_IRQ_SW0;
+ /*
+ * We need to disable interrupts to make sure our updates are
+ * atomic.
+ */
+ local_irq_save(flags);
+ clear_c0_status(0x100 << bit);
+ local_irq_restore(flags);
+}
+
+static void octeon_irq_core_disable(unsigned int irq)
+{
+#ifdef CONFIG_SMP
+ on_each_cpu((void (*)(void *)) octeon_irq_core_disable_local,
+ (void *) (long) irq, 1);
+#else
+ octeon_irq_core_disable_local(irq);
+#endif
+}
+
+static struct irq_chip octeon_irq_chip_core = {
+ .name = "Core",
+ .enable = octeon_irq_core_enable,
+ .disable = octeon_irq_core_disable,
+ .ack = octeon_irq_core_ack,
+ .eoi = octeon_irq_core_eoi,
+};
+
+
+static void octeon_irq_ciu0_ack(unsigned int irq)
+{
+ /*
+ * In order to avoid any locking accessing the CIU, we
+ * acknowledge CIU interrupts by disabling all of them. This
+ * way we can use a per core register and avoid any out of
+ * core locking requirements. This has the side affect that
+ * CIU interrupts can't be processed recursively.
+ *
+ * We don't need to disable IRQs to make these atomic since
+ * they are already disabled earlier in the low level
+ * interrupt code.
+ */
+ clear_c0_status(0x100 << 2);
+}
+
+static void octeon_irq_ciu0_eoi(unsigned int irq)
+{
+ /*
+ * Enable all CIU interrupts again. We don't need to disable
+ * IRQs to make these atomic since they are already disabled
+ * earlier in the low level interrupt code.
+ */
+ set_c0_status(0x100 << 2);
+}
+
+static void octeon_irq_ciu0_enable(unsigned int irq)
+{
+ int coreid = cvmx_get_core_num();
+ unsigned long flags;
+ uint64_t en0;
+ int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
+
+ /*
+ * A read lock is used here to make sure only one core is ever
+ * updating the CIU enable bits at a time. During an enable
+ * the cores don't interfere with each other. During a disable
+ * the write lock stops any enables that might cause a
+ * problem.
+ */
+ read_lock_irqsave(&octeon_irq_ciu0_rwlock, flags);
+ en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
+ en0 |= 1ull << bit;
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
+ cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
+ read_unlock_irqrestore(&octeon_irq_ciu0_rwlock, flags);
+}
+
+static void octeon_irq_ciu0_disable(unsigned int irq)
+{
+ int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
+ unsigned long flags;
+ uint64_t en0;
+#ifdef CONFIG_SMP
+ int cpu;
+ write_lock_irqsave(&octeon_irq_ciu0_rwlock, flags);
+ for_each_online_cpu(cpu) {
+ int coreid = cpu_logical_map(cpu);
+ en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
+ en0 &= ~(1ull << bit);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
+ }
+ /*
+ * We need to do a read after the last update to make sure all
+ * of them are done.
+ */
+ cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
+ write_unlock_irqrestore(&octeon_irq_ciu0_rwlock, flags);
+#else
+ int coreid = cvmx_get_core_num();
+ local_irq_save(flags);
+ en0 = cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
+ en0 &= ~(1ull << bit);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
+ cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
+ local_irq_restore(flags);
+#endif
+}
+
+#ifdef CONFIG_SMP
+static void octeon_irq_ciu0_set_affinity(unsigned int irq, const struct cpumask *dest)
+{
+ int cpu;
+ int bit = irq - OCTEON_IRQ_WORKQ0; /* Bit 0-63 of EN0 */
+
+ write_lock(&octeon_irq_ciu0_rwlock);
+ for_each_online_cpu(cpu) {
+ int coreid = cpu_logical_map(cpu);
+ uint64_t en0 =
+ cvmx_read_csr(CVMX_CIU_INTX_EN0(coreid * 2));
+ if (cpumask_test_cpu(cpu, dest))
+ en0 |= 1ull << bit;
+ else
+ en0 &= ~(1ull << bit);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0(coreid * 2), en0);
+ }
+ /*
+ * We need to do a read after the last update to make sure all
+ * of them are done.
+ */
+ cvmx_read_csr(CVMX_CIU_INTX_EN0(cvmx_get_core_num() * 2));
+ write_unlock(&octeon_irq_ciu0_rwlock);
+}
+#endif
+
+static struct irq_chip octeon_irq_chip_ciu0 = {
+ .name = "CIU0",
+ .enable = octeon_irq_ciu0_enable,
+ .disable = octeon_irq_ciu0_disable,
+ .ack = octeon_irq_ciu0_ack,
+ .eoi = octeon_irq_ciu0_eoi,
+#ifdef CONFIG_SMP
+ .set_affinity = octeon_irq_ciu0_set_affinity,
+#endif
+};
+
+
+static void octeon_irq_ciu1_ack(unsigned int irq)
+{
+ /*
+ * In order to avoid any locking accessing the CIU, we
+ * acknowledge CIU interrupts by disabling all of them. This
+ * way we can use a per core register and avoid any out of
+ * core locking requirements. This has the side affect that
+ * CIU interrupts can't be processed recursively. We don't
+ * need to disable IRQs to make these atomic since they are
+ * already disabled earlier in the low level interrupt code.
+ */
+ clear_c0_status(0x100 << 3);
+}
+
+static void octeon_irq_ciu1_eoi(unsigned int irq)
+{
+ /*
+ * Enable all CIU interrupts again. We don't need to disable
+ * IRQs to make these atomic since they are already disabled
+ * earlier in the low level interrupt code.
+ */
+ set_c0_status(0x100 << 3);
+}
+
+static void octeon_irq_ciu1_enable(unsigned int irq)
+{
+ int coreid = cvmx_get_core_num();
+ unsigned long flags;
+ uint64_t en1;
+ int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
+
+ /*
+ * A read lock is used here to make sure only one core is ever
+ * updating the CIU enable bits at a time. During an enable
+ * the cores don't interfere with each other. During a disable
+ * the write lock stops any enables that might cause a
+ * problem.
+ */
+ read_lock_irqsave(&octeon_irq_ciu1_rwlock, flags);
+ en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
+ en1 |= 1ull << bit;
+ cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
+ cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
+ read_unlock_irqrestore(&octeon_irq_ciu1_rwlock, flags);
+}
+
+static void octeon_irq_ciu1_disable(unsigned int irq)
+{
+ int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
+ unsigned long flags;
+ uint64_t en1;
+#ifdef CONFIG_SMP
+ int cpu;
+ write_lock_irqsave(&octeon_irq_ciu1_rwlock, flags);
+ for_each_online_cpu(cpu) {
+ int coreid = cpu_logical_map(cpu);
+ en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
+ en1 &= ~(1ull << bit);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
+ }
+ /*
+ * We need to do a read after the last update to make sure all
+ * of them are done.
+ */
+ cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
+ write_unlock_irqrestore(&octeon_irq_ciu1_rwlock, flags);
+#else
+ int coreid = cvmx_get_core_num();
+ local_irq_save(flags);
+ en1 = cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
+ en1 &= ~(1ull << bit);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
+ cvmx_read_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1));
+ local_irq_restore(flags);
+#endif
+}
+
+#ifdef CONFIG_SMP
+static void octeon_irq_ciu1_set_affinity(unsigned int irq, const struct cpumask *dest)
+{
+ int cpu;
+ int bit = irq - OCTEON_IRQ_WDOG0; /* Bit 0-63 of EN1 */
+
+ write_lock(&octeon_irq_ciu1_rwlock);
+ for_each_online_cpu(cpu) {
+ int coreid = cpu_logical_map(cpu);
+ uint64_t en1 =
+ cvmx_read_csr(CVMX_CIU_INTX_EN1
+ (coreid * 2 + 1));
+ if (cpumask_test_cpu(cpu, dest))
+ en1 |= 1ull << bit;
+ else
+ en1 &= ~(1ull << bit);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1(coreid * 2 + 1), en1);
+ }
+ /*
+ * We need to do a read after the last update to make sure all
+ * of them are done.
+ */
+ cvmx_read_csr(CVMX_CIU_INTX_EN1(cvmx_get_core_num() * 2 + 1));
+ write_unlock(&octeon_irq_ciu1_rwlock);
+}
+#endif
+
+static struct irq_chip octeon_irq_chip_ciu1 = {
+ .name = "CIU1",
+ .enable = octeon_irq_ciu1_enable,
+ .disable = octeon_irq_ciu1_disable,
+ .ack = octeon_irq_ciu1_ack,
+ .eoi = octeon_irq_ciu1_eoi,
+#ifdef CONFIG_SMP
+ .set_affinity = octeon_irq_ciu1_set_affinity,
+#endif
+};
+
+#ifdef CONFIG_PCI_MSI
+
+static void octeon_irq_msi_ack(unsigned int irq)
+{
+ if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
+ /* These chips have PCI */
+ cvmx_write_csr(CVMX_NPI_NPI_MSI_RCV,
+ 1ull << (irq - OCTEON_IRQ_MSI_BIT0));
+ } else {
+ /*
+ * These chips have PCIe. Thankfully the ACK doesn't
+ * need any locking.
+ */
+ cvmx_write_csr(CVMX_PEXP_NPEI_MSI_RCV0,
+ 1ull << (irq - OCTEON_IRQ_MSI_BIT0));
+ }
+}
+
+static void octeon_irq_msi_eoi(unsigned int irq)
+{
+ /* Nothing needed */
+}
+
+static void octeon_irq_msi_enable(unsigned int irq)
+{
+ if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
+ /*
+ * Octeon PCI doesn't have the ability to mask/unmask
+ * MSI interrupts individually. Instead of
+ * masking/unmasking them in groups of 16, we simple
+ * assume MSI devices are well behaved. MSI
+ * interrupts are always enable and the ACK is assumed
+ * to be enough.
+ */
+ } else {
+ /* These chips have PCIe. Note that we only support
+ * the first 64 MSI interrupts. Unfortunately all the
+ * MSI enables are in the same register. We use
+ * MSI0's lock to control access to them all.
+ */
+ uint64_t en;
+ unsigned long flags;
+ spin_lock_irqsave(&octeon_irq_msi_lock, flags);
+ en = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
+ en |= 1ull << (irq - OCTEON_IRQ_MSI_BIT0);
+ cvmx_write_csr(CVMX_PEXP_NPEI_MSI_ENB0, en);
+ cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
+ spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
+ }
+}
+
+static void octeon_irq_msi_disable(unsigned int irq)
+{
+ if (!octeon_has_feature(OCTEON_FEATURE_PCIE)) {
+ /* See comment in enable */
+ } else {
+ /*
+ * These chips have PCIe. Note that we only support
+ * the first 64 MSI interrupts. Unfortunately all the
+ * MSI enables are in the same register. We use
+ * MSI0's lock to control access to them all.
+ */
+ uint64_t en;
+ unsigned long flags;
+ spin_lock_irqsave(&octeon_irq_msi_lock, flags);
+ en = cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
+ en &= ~(1ull << (irq - OCTEON_IRQ_MSI_BIT0));
+ cvmx_write_csr(CVMX_PEXP_NPEI_MSI_ENB0, en);
+ cvmx_read_csr(CVMX_PEXP_NPEI_MSI_ENB0);
+ spin_unlock_irqrestore(&octeon_irq_msi_lock, flags);
+ }
+}
+
+static struct irq_chip octeon_irq_chip_msi = {
+ .name = "MSI",
+ .enable = octeon_irq_msi_enable,
+ .disable = octeon_irq_msi_disable,
+ .ack = octeon_irq_msi_ack,
+ .eoi = octeon_irq_msi_eoi,
+};
+#endif
+
+void __init arch_init_irq(void)
+{
+ int irq;
+
+#ifdef CONFIG_SMP
+ /* Set the default affinity to the boot cpu. */
+ cpumask_clear(irq_default_affinity);
+ cpumask_set_cpu(smp_processor_id(), irq_default_affinity);
+#endif
+
+ if (NR_IRQS < OCTEON_IRQ_LAST)
+ pr_err("octeon_irq_init: NR_IRQS is set too low\n");
+
+ /* 0 - 15 reserved for i8259 master and slave controller. */
+
+ /* 17 - 23 Mips internal */
+ for (irq = OCTEON_IRQ_SW0; irq <= OCTEON_IRQ_TIMER; irq++) {
+ set_irq_chip_and_handler(irq, &octeon_irq_chip_core,
+ handle_percpu_irq);
+ }
+
+ /* 24 - 87 CIU_INT_SUM0 */
+ for (irq = OCTEON_IRQ_WORKQ0; irq <= OCTEON_IRQ_BOOTDMA; irq++) {
+ set_irq_chip_and_handler(irq, &octeon_irq_chip_ciu0,
+ handle_percpu_irq);
+ }
+
+ /* 88 - 151 CIU_INT_SUM1 */
+ for (irq = OCTEON_IRQ_WDOG0; irq <= OCTEON_IRQ_RESERVED151; irq++) {
+ set_irq_chip_and_handler(irq, &octeon_irq_chip_ciu1,
+ handle_percpu_irq);
+ }
+
+#ifdef CONFIG_PCI_MSI
+ /* 152 - 215 PCI/PCIe MSI interrupts */
+ for (irq = OCTEON_IRQ_MSI_BIT0; irq <= OCTEON_IRQ_MSI_BIT63; irq++) {
+ set_irq_chip_and_handler(irq, &octeon_irq_chip_msi,
+ handle_percpu_irq);
+ }
+#endif
+ set_c0_status(0x300 << 2);
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ const unsigned long core_id = cvmx_get_core_num();
+ const uint64_t ciu_sum0_address = CVMX_CIU_INTX_SUM0(core_id * 2);
+ const uint64_t ciu_en0_address = CVMX_CIU_INTX_EN0(core_id * 2);
+ const uint64_t ciu_sum1_address = CVMX_CIU_INT_SUM1;
+ const uint64_t ciu_en1_address = CVMX_CIU_INTX_EN1(core_id * 2 + 1);
+ unsigned long cop0_cause;
+ unsigned long cop0_status;
+ uint64_t ciu_en;
+ uint64_t ciu_sum;
+
+ while (1) {
+ cop0_cause = read_c0_cause();
+ cop0_status = read_c0_status();
+ cop0_cause &= cop0_status;
+ cop0_cause &= ST0_IM;
+
+ if (unlikely(cop0_cause & STATUSF_IP2)) {
+ ciu_sum = cvmx_read_csr(ciu_sum0_address);
+ ciu_en = cvmx_read_csr(ciu_en0_address);
+ ciu_sum &= ciu_en;
+ if (likely(ciu_sum))
+ do_IRQ(fls64(ciu_sum) + OCTEON_IRQ_WORKQ0 - 1);
+ else
+ spurious_interrupt();
+ } else if (unlikely(cop0_cause & STATUSF_IP3)) {
+ ciu_sum = cvmx_read_csr(ciu_sum1_address);
+ ciu_en = cvmx_read_csr(ciu_en1_address);
+ ciu_sum &= ciu_en;
+ if (likely(ciu_sum))
+ do_IRQ(fls64(ciu_sum) + OCTEON_IRQ_WDOG0 - 1);
+ else
+ spurious_interrupt();
+ } else if (likely(cop0_cause)) {
+ do_IRQ(fls(cop0_cause) - 9 + MIPS_CPU_IRQ_BASE);
+ } else {
+ break;
+ }
+ }
+}
diff --git a/arch/mips/cavium-octeon/octeon-memcpy.S b/arch/mips/cavium-octeon/octeon-memcpy.S
new file mode 100644
index 0000000..88e0cdd
--- /dev/null
+++ b/arch/mips/cavium-octeon/octeon-memcpy.S
@@ -0,0 +1,521 @@
+/*
+ * 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.
+ *
+ * Unified implementation of memcpy, memmove and the __copy_user backend.
+ *
+ * Copyright (C) 1998, 99, 2000, 01, 2002 Ralf Baechle (ralf@gnu.org)
+ * Copyright (C) 1999, 2000, 01, 2002 Silicon Graphics, Inc.
+ * Copyright (C) 2002 Broadcom, Inc.
+ * memcpy/copy_user author: Mark Vandevoorde
+ *
+ * Mnemonic names for arguments to memcpy/__copy_user
+ */
+
+#include <asm/asm.h>
+#include <asm/asm-offsets.h>
+#include <asm/regdef.h>
+
+#define dst a0
+#define src a1
+#define len a2
+
+/*
+ * Spec
+ *
+ * memcpy copies len bytes from src to dst and sets v0 to dst.
+ * It assumes that
+ * - src and dst don't overlap
+ * - src is readable
+ * - dst is writable
+ * memcpy uses the standard calling convention
+ *
+ * __copy_user copies up to len bytes from src to dst and sets a2 (len) to
+ * the number of uncopied bytes due to an exception caused by a read or write.
+ * __copy_user assumes that src and dst don't overlap, and that the call is
+ * implementing one of the following:
+ * copy_to_user
+ * - src is readable (no exceptions when reading src)
+ * copy_from_user
+ * - dst is writable (no exceptions when writing dst)
+ * __copy_user uses a non-standard calling convention; see
+ * arch/mips/include/asm/uaccess.h
+ *
+ * When an exception happens on a load, the handler must
+ # ensure that all of the destination buffer is overwritten to prevent
+ * leaking information to user mode programs.
+ */
+
+/*
+ * Implementation
+ */
+
+/*
+ * The exception handler for loads requires that:
+ * 1- AT contain the address of the byte just past the end of the source
+ * of the copy,
+ * 2- src_entry <= src < AT, and
+ * 3- (dst - src) == (dst_entry - src_entry),
+ * The _entry suffix denotes values when __copy_user was called.
+ *
+ * (1) is set up up by uaccess.h and maintained by not writing AT in copy_user
+ * (2) is met by incrementing src by the number of bytes copied
+ * (3) is met by not doing loads between a pair of increments of dst and src
+ *
+ * The exception handlers for stores adjust len (if necessary) and return.
+ * These handlers do not need to overwrite any data.
+ *
+ * For __rmemcpy and memmove an exception is always a kernel bug, therefore
+ * they're not protected.
+ */
+
+#define EXC(inst_reg,addr,handler) \
+9: inst_reg, addr; \
+ .section __ex_table,"a"; \
+ PTR 9b, handler; \
+ .previous
+
+/*
+ * Only on the 64-bit kernel we can made use of 64-bit registers.
+ */
+#ifdef CONFIG_64BIT
+#define USE_DOUBLE
+#endif
+
+#ifdef USE_DOUBLE
+
+#define LOAD ld
+#define LOADL ldl
+#define LOADR ldr
+#define STOREL sdl
+#define STORER sdr
+#define STORE sd
+#define ADD daddu
+#define SUB dsubu
+#define SRL dsrl
+#define SRA dsra
+#define SLL dsll
+#define SLLV dsllv
+#define SRLV dsrlv
+#define NBYTES 8
+#define LOG_NBYTES 3
+
+/*
+ * As we are sharing code base with the mips32 tree (which use the o32 ABI
+ * register definitions). We need to redefine the register definitions from
+ * the n64 ABI register naming to the o32 ABI register naming.
+ */
+#undef t0
+#undef t1
+#undef t2
+#undef t3
+#define t0 $8
+#define t1 $9
+#define t2 $10
+#define t3 $11
+#define t4 $12
+#define t5 $13
+#define t6 $14
+#define t7 $15
+
+#else
+
+#define LOAD lw
+#define LOADL lwl
+#define LOADR lwr
+#define STOREL swl
+#define STORER swr
+#define STORE sw
+#define ADD addu
+#define SUB subu
+#define SRL srl
+#define SLL sll
+#define SRA sra
+#define SLLV sllv
+#define SRLV srlv
+#define NBYTES 4
+#define LOG_NBYTES 2
+
+#endif /* USE_DOUBLE */
+
+#ifdef CONFIG_CPU_LITTLE_ENDIAN
+#define LDFIRST LOADR
+#define LDREST LOADL
+#define STFIRST STORER
+#define STREST STOREL
+#define SHIFT_DISCARD SLLV
+#else
+#define LDFIRST LOADL
+#define LDREST LOADR
+#define STFIRST STOREL
+#define STREST STORER
+#define SHIFT_DISCARD SRLV
+#endif
+
+#define FIRST(unit) ((unit)*NBYTES)
+#define REST(unit) (FIRST(unit)+NBYTES-1)
+#define UNIT(unit) FIRST(unit)
+
+#define ADDRMASK (NBYTES-1)
+
+ .text
+ .set noreorder
+ .set noat
+
+/*
+ * A combined memcpy/__copy_user
+ * __copy_user sets len to 0 for success; else to an upper bound of
+ * the number of uncopied bytes.
+ * memcpy sets v0 to dst.
+ */
+ .align 5
+LEAF(memcpy) /* a0=dst a1=src a2=len */
+ move v0, dst /* return value */
+__memcpy:
+FEXPORT(__copy_user)
+ /*
+ * Note: dst & src may be unaligned, len may be 0
+ * Temps
+ */
+ #
+ # Octeon doesn't care if the destination is unaligned. The hardware
+ # can fix it faster than we can special case the assembly.
+ #
+ pref 0, 0(src)
+ sltu t0, len, NBYTES # Check if < 1 word
+ bnez t0, copy_bytes_checklen
+ and t0, src, ADDRMASK # Check if src unaligned
+ bnez t0, src_unaligned
+ sltu t0, len, 4*NBYTES # Check if < 4 words
+ bnez t0, less_than_4units
+ sltu t0, len, 8*NBYTES # Check if < 8 words
+ bnez t0, less_than_8units
+ sltu t0, len, 16*NBYTES # Check if < 16 words
+ bnez t0, cleanup_both_aligned
+ sltu t0, len, 128+1 # Check if len < 129
+ bnez t0, 1f # Skip prefetch if len is too short
+ sltu t0, len, 256+1 # Check if len < 257
+ bnez t0, 1f # Skip prefetch if len is too short
+ pref 0, 128(src) # We must not prefetch invalid addresses
+ #
+ # This is where we loop if there is more than 128 bytes left
+2: pref 0, 256(src) # We must not prefetch invalid addresses
+ #
+ # This is where we loop if we can't prefetch anymore
+1:
+EXC( LOAD t0, UNIT(0)(src), l_exc)
+EXC( LOAD t1, UNIT(1)(src), l_exc_copy)
+EXC( LOAD t2, UNIT(2)(src), l_exc_copy)
+EXC( LOAD t3, UNIT(3)(src), l_exc_copy)
+ SUB len, len, 16*NBYTES
+EXC( STORE t0, UNIT(0)(dst), s_exc_p16u)
+EXC( STORE t1, UNIT(1)(dst), s_exc_p15u)
+EXC( STORE t2, UNIT(2)(dst), s_exc_p14u)
+EXC( STORE t3, UNIT(3)(dst), s_exc_p13u)
+EXC( LOAD t0, UNIT(4)(src), l_exc_copy)
+EXC( LOAD t1, UNIT(5)(src), l_exc_copy)
+EXC( LOAD t2, UNIT(6)(src), l_exc_copy)
+EXC( LOAD t3, UNIT(7)(src), l_exc_copy)
+EXC( STORE t0, UNIT(4)(dst), s_exc_p12u)
+EXC( STORE t1, UNIT(5)(dst), s_exc_p11u)
+EXC( STORE t2, UNIT(6)(dst), s_exc_p10u)
+ ADD src, src, 16*NBYTES
+EXC( STORE t3, UNIT(7)(dst), s_exc_p9u)
+ ADD dst, dst, 16*NBYTES
+EXC( LOAD t0, UNIT(-8)(src), l_exc_copy)
+EXC( LOAD t1, UNIT(-7)(src), l_exc_copy)
+EXC( LOAD t2, UNIT(-6)(src), l_exc_copy)
+EXC( LOAD t3, UNIT(-5)(src), l_exc_copy)
+EXC( STORE t0, UNIT(-8)(dst), s_exc_p8u)
+EXC( STORE t1, UNIT(-7)(dst), s_exc_p7u)
+EXC( STORE t2, UNIT(-6)(dst), s_exc_p6u)
+EXC( STORE t3, UNIT(-5)(dst), s_exc_p5u)
+EXC( LOAD t0, UNIT(-4)(src), l_exc_copy)
+EXC( LOAD t1, UNIT(-3)(src), l_exc_copy)
+EXC( LOAD t2, UNIT(-2)(src), l_exc_copy)
+EXC( LOAD t3, UNIT(-1)(src), l_exc_copy)
+EXC( STORE t0, UNIT(-4)(dst), s_exc_p4u)
+EXC( STORE t1, UNIT(-3)(dst), s_exc_p3u)
+EXC( STORE t2, UNIT(-2)(dst), s_exc_p2u)
+EXC( STORE t3, UNIT(-1)(dst), s_exc_p1u)
+ sltu t0, len, 256+1 # See if we can prefetch more
+ beqz t0, 2b
+ sltu t0, len, 128 # See if we can loop more time
+ beqz t0, 1b
+ nop
+ #
+ # Jump here if there are less than 16*NBYTES left.
+ #
+cleanup_both_aligned:
+ beqz len, done
+ sltu t0, len, 8*NBYTES
+ bnez t0, less_than_8units
+ nop
+EXC( LOAD t0, UNIT(0)(src), l_exc)
+EXC( LOAD t1, UNIT(1)(src), l_exc_copy)
+EXC( LOAD t2, UNIT(2)(src), l_exc_copy)
+EXC( LOAD t3, UNIT(3)(src), l_exc_copy)
+ SUB len, len, 8*NBYTES
+EXC( STORE t0, UNIT(0)(dst), s_exc_p8u)
+EXC( STORE t1, UNIT(1)(dst), s_exc_p7u)
+EXC( STORE t2, UNIT(2)(dst), s_exc_p6u)
+EXC( STORE t3, UNIT(3)(dst), s_exc_p5u)
+EXC( LOAD t0, UNIT(4)(src), l_exc_copy)
+EXC( LOAD t1, UNIT(5)(src), l_exc_copy)
+EXC( LOAD t2, UNIT(6)(src), l_exc_copy)
+EXC( LOAD t3, UNIT(7)(src), l_exc_copy)
+EXC( STORE t0, UNIT(4)(dst), s_exc_p4u)
+EXC( STORE t1, UNIT(5)(dst), s_exc_p3u)
+EXC( STORE t2, UNIT(6)(dst), s_exc_p2u)
+EXC( STORE t3, UNIT(7)(dst), s_exc_p1u)
+ ADD src, src, 8*NBYTES
+ beqz len, done
+ ADD dst, dst, 8*NBYTES
+ #
+ # Jump here if there are less than 8*NBYTES left.
+ #
+less_than_8units:
+ sltu t0, len, 4*NBYTES
+ bnez t0, less_than_4units
+ nop
+EXC( LOAD t0, UNIT(0)(src), l_exc)
+EXC( LOAD t1, UNIT(1)(src), l_exc_copy)
+EXC( LOAD t2, UNIT(2)(src), l_exc_copy)
+EXC( LOAD t3, UNIT(3)(src), l_exc_copy)
+ SUB len, len, 4*NBYTES
+EXC( STORE t0, UNIT(0)(dst), s_exc_p4u)
+EXC( STORE t1, UNIT(1)(dst), s_exc_p3u)
+EXC( STORE t2, UNIT(2)(dst), s_exc_p2u)
+EXC( STORE t3, UNIT(3)(dst), s_exc_p1u)
+ ADD src, src, 4*NBYTES
+ beqz len, done
+ ADD dst, dst, 4*NBYTES
+ #
+ # Jump here if there are less than 4*NBYTES left. This means
+ # we may need to copy up to 3 NBYTES words.
+ #
+less_than_4units:
+ sltu t0, len, 1*NBYTES
+ bnez t0, copy_bytes_checklen
+ nop
+ #
+ # 1) Copy NBYTES, then check length again
+ #
+EXC( LOAD t0, 0(src), l_exc)
+ SUB len, len, NBYTES
+ sltu t1, len, 8
+EXC( STORE t0, 0(dst), s_exc_p1u)
+ ADD src, src, NBYTES
+ bnez t1, copy_bytes_checklen
+ ADD dst, dst, NBYTES
+ #
+ # 2) Copy NBYTES, then check length again
+ #
+EXC( LOAD t0, 0(src), l_exc)
+ SUB len, len, NBYTES
+ sltu t1, len, 8
+EXC( STORE t0, 0(dst), s_exc_p1u)
+ ADD src, src, NBYTES
+ bnez t1, copy_bytes_checklen
+ ADD dst, dst, NBYTES
+ #
+ # 3) Copy NBYTES, then check length again
+ #
+EXC( LOAD t0, 0(src), l_exc)
+ SUB len, len, NBYTES
+ ADD src, src, NBYTES
+ ADD dst, dst, NBYTES
+ b copy_bytes_checklen
+EXC( STORE t0, -8(dst), s_exc_p1u)
+
+src_unaligned:
+#define rem t8
+ SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter
+ beqz t0, cleanup_src_unaligned
+ and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES
+1:
+/*
+ * Avoid consecutive LD*'s to the same register since some mips
+ * implementations can't issue them in the same cycle.
+ * It's OK to load FIRST(N+1) before REST(N) because the two addresses
+ * are to the same unit (unless src is aligned, but it's not).
+ */
+EXC( LDFIRST t0, FIRST(0)(src), l_exc)
+EXC( LDFIRST t1, FIRST(1)(src), l_exc_copy)
+ SUB len, len, 4*NBYTES
+EXC( LDREST t0, REST(0)(src), l_exc_copy)
+EXC( LDREST t1, REST(1)(src), l_exc_copy)
+EXC( LDFIRST t2, FIRST(2)(src), l_exc_copy)
+EXC( LDFIRST t3, FIRST(3)(src), l_exc_copy)
+EXC( LDREST t2, REST(2)(src), l_exc_copy)
+EXC( LDREST t3, REST(3)(src), l_exc_copy)
+ ADD src, src, 4*NBYTES
+EXC( STORE t0, UNIT(0)(dst), s_exc_p4u)
+EXC( STORE t1, UNIT(1)(dst), s_exc_p3u)
+EXC( STORE t2, UNIT(2)(dst), s_exc_p2u)
+EXC( STORE t3, UNIT(3)(dst), s_exc_p1u)
+ bne len, rem, 1b
+ ADD dst, dst, 4*NBYTES
+
+cleanup_src_unaligned:
+ beqz len, done
+ and rem, len, NBYTES-1 # rem = len % NBYTES
+ beq rem, len, copy_bytes
+ nop
+1:
+EXC( LDFIRST t0, FIRST(0)(src), l_exc)
+EXC( LDREST t0, REST(0)(src), l_exc_copy)
+ SUB len, len, NBYTES
+EXC( STORE t0, 0(dst), s_exc_p1u)
+ ADD src, src, NBYTES
+ bne len, rem, 1b
+ ADD dst, dst, NBYTES
+
+copy_bytes_checklen:
+ beqz len, done
+ nop
+copy_bytes:
+ /* 0 < len < NBYTES */
+#define COPY_BYTE(N) \
+EXC( lb t0, N(src), l_exc); \
+ SUB len, len, 1; \
+ beqz len, done; \
+EXC( sb t0, N(dst), s_exc_p1)
+
+ COPY_BYTE(0)
+ COPY_BYTE(1)
+#ifdef USE_DOUBLE
+ COPY_BYTE(2)
+ COPY_BYTE(3)
+ COPY_BYTE(4)
+ COPY_BYTE(5)
+#endif
+EXC( lb t0, NBYTES-2(src), l_exc)
+ SUB len, len, 1
+ jr ra
+EXC( sb t0, NBYTES-2(dst), s_exc_p1)
+done:
+ jr ra
+ nop
+ END(memcpy)
+
+l_exc_copy:
+ /*
+ * Copy bytes from src until faulting load address (or until a
+ * lb faults)
+ *
+ * When reached by a faulting LDFIRST/LDREST, THREAD_BUADDR($28)
+ * may be more than a byte beyond the last address.
+ * Hence, the lb below may get an exception.
+ *
+ * Assumes src < THREAD_BUADDR($28)
+ */
+ LOAD t0, TI_TASK($28)
+ nop
+ LOAD t0, THREAD_BUADDR(t0)
+1:
+EXC( lb t1, 0(src), l_exc)
+ ADD src, src, 1
+ sb t1, 0(dst) # can't fault -- we're copy_from_user
+ bne src, t0, 1b
+ ADD dst, dst, 1
+l_exc:
+ LOAD t0, TI_TASK($28)
+ nop
+ LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address
+ nop
+ SUB len, AT, t0 # len number of uncopied bytes
+ /*
+ * Here's where we rely on src and dst being incremented in tandem,
+ * See (3) above.
+ * dst += (fault addr - src) to put dst at first byte to clear
+ */
+ ADD dst, t0 # compute start address in a1
+ SUB dst, src
+ /*
+ * Clear len bytes starting at dst. Can't call __bzero because it
+ * might modify len. An inefficient loop for these rare times...
+ */
+ beqz len, done
+ SUB src, len, 1
+1: sb zero, 0(dst)
+ ADD dst, dst, 1
+ bnez src, 1b
+ SUB src, src, 1
+ jr ra
+ nop
+
+
+#define SEXC(n) \
+s_exc_p ## n ## u: \
+ jr ra; \
+ ADD len, len, n*NBYTES
+
+SEXC(16)
+SEXC(15)
+SEXC(14)
+SEXC(13)
+SEXC(12)
+SEXC(11)
+SEXC(10)
+SEXC(9)
+SEXC(8)
+SEXC(7)
+SEXC(6)
+SEXC(5)
+SEXC(4)
+SEXC(3)
+SEXC(2)
+SEXC(1)
+
+s_exc_p1:
+ jr ra
+ ADD len, len, 1
+s_exc:
+ jr ra
+ nop
+
+ .align 5
+LEAF(memmove)
+ ADD t0, a0, a2
+ ADD t1, a1, a2
+ sltu t0, a1, t0 # dst + len <= src -> memcpy
+ sltu t1, a0, t1 # dst >= src + len -> memcpy
+ and t0, t1
+ beqz t0, __memcpy
+ move v0, a0 /* return value */
+ beqz a2, r_out
+ END(memmove)
+
+ /* fall through to __rmemcpy */
+LEAF(__rmemcpy) /* a0=dst a1=src a2=len */
+ sltu t0, a1, a0
+ beqz t0, r_end_bytes_up # src >= dst
+ nop
+ ADD a0, a2 # dst = dst + len
+ ADD a1, a2 # src = src + len
+
+r_end_bytes:
+ lb t0, -1(a1)
+ SUB a2, a2, 0x1
+ sb t0, -1(a0)
+ SUB a1, a1, 0x1
+ bnez a2, r_end_bytes
+ SUB a0, a0, 0x1
+
+r_out:
+ jr ra
+ move a2, zero
+
+r_end_bytes_up:
+ lb t0, (a1)
+ SUB a2, a2, 0x1
+ sb t0, (a0)
+ ADD a1, a1, 0x1
+ bnez a2, r_end_bytes_up
+ ADD a0, a0, 0x1
+
+ jr ra
+ move a2, zero
+ END(__rmemcpy)
diff --git a/arch/mips/cavium-octeon/serial.c b/arch/mips/cavium-octeon/serial.c
new file mode 100644
index 0000000..8240728
--- /dev/null
+++ b/arch/mips/cavium-octeon/serial.c
@@ -0,0 +1,136 @@
+/*
+ * 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-2007 Cavium Networks
+ */
+#include <linux/console.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/platform_device.h>
+#include <linux/serial.h>
+#include <linux/serial_8250.h>
+#include <linux/serial_reg.h>
+#include <linux/tty.h>
+
+#include <asm/time.h>
+
+#include <asm/octeon/octeon.h>
+
+#ifdef CONFIG_GDB_CONSOLE
+#define DEBUG_UART 0
+#else
+#define DEBUG_UART 1
+#endif
+
+unsigned int octeon_serial_in(struct uart_port *up, int offset)
+{
+ int rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3)));
+ if (offset == UART_IIR && (rv & 0xf) == 7) {
+ /* Busy interrupt, read the USR (39) and try again. */
+ cvmx_read_csr((uint64_t)(up->membase + (39 << 3)));
+ rv = cvmx_read_csr((uint64_t)(up->membase + (offset << 3)));
+ }
+ return rv;
+}
+
+void octeon_serial_out(struct uart_port *up, int offset, int value)
+{
+ /*
+ * If bits 6 or 7 of the OCTEON UART's LCR are set, it quits
+ * working.
+ */
+ if (offset == UART_LCR)
+ value &= 0x9f;
+ cvmx_write_csr((uint64_t)(up->membase + (offset << 3)), (u8)value);
+}
+
+/*
+ * Allocated in .bss, so it is all zeroed.
+ */
+#define OCTEON_MAX_UARTS 3
+static struct plat_serial8250_port octeon_uart8250_data[OCTEON_MAX_UARTS + 1];
+static struct platform_device octeon_uart8250_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = octeon_uart8250_data,
+ },
+};
+
+static void __init octeon_uart_set_common(struct plat_serial8250_port *p)
+{
+ p->flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE;
+ p->type = PORT_OCTEON;
+ p->iotype = UPIO_MEM;
+ p->regshift = 3; /* I/O addresses are every 8 bytes */
+ p->uartclk = mips_hpt_frequency;
+ p->serial_in = octeon_serial_in;
+ p->serial_out = octeon_serial_out;
+}
+
+static int __init octeon_serial_init(void)
+{
+ int enable_uart0;
+ int enable_uart1;
+ int enable_uart2;
+ struct plat_serial8250_port *p;
+
+#ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
+ /*
+ * If we are configured to run as the second of two kernels,
+ * disable uart0 and enable uart1. Uart0 is owned by the first
+ * kernel
+ */
+ enable_uart0 = 0;
+ enable_uart1 = 1;
+#else
+ /*
+ * We are configured for the first kernel. We'll enable uart0
+ * if the bootloader told us to use 0, otherwise will enable
+ * uart 1.
+ */
+ enable_uart0 = (octeon_get_boot_uart() == 0);
+ enable_uart1 = (octeon_get_boot_uart() == 1);
+#ifdef CONFIG_KGDB
+ enable_uart1 = 1;
+#endif
+#endif
+
+ /* Right now CN52XX is the only chip with a third uart */
+ enable_uart2 = OCTEON_IS_MODEL(OCTEON_CN52XX);
+
+ p = octeon_uart8250_data;
+ if (enable_uart0) {
+ /* Add a ttyS device for hardware uart 0 */
+ octeon_uart_set_common(p);
+ p->membase = (void *) CVMX_MIO_UARTX_RBR(0);
+ p->mapbase = CVMX_MIO_UARTX_RBR(0) & ((1ull << 49) - 1);
+ p->irq = OCTEON_IRQ_UART0;
+ p++;
+ }
+
+ if (enable_uart1) {
+ /* Add a ttyS device for hardware uart 1 */
+ octeon_uart_set_common(p);
+ p->membase = (void *) CVMX_MIO_UARTX_RBR(1);
+ p->mapbase = CVMX_MIO_UARTX_RBR(1) & ((1ull << 49) - 1);
+ p->irq = OCTEON_IRQ_UART1;
+ p++;
+ }
+ if (enable_uart2) {
+ /* Add a ttyS device for hardware uart 2 */
+ octeon_uart_set_common(p);
+ p->membase = (void *) CVMX_MIO_UART2_RBR;
+ p->mapbase = CVMX_MIO_UART2_RBR & ((1ull << 49) - 1);
+ p->irq = OCTEON_IRQ_UART2;
+ p++;
+ }
+
+ BUG_ON(p > &octeon_uart8250_data[OCTEON_MAX_UARTS]);
+
+ return platform_device_register(&octeon_uart8250_device);
+}
+
+device_initcall(octeon_serial_init);
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
new file mode 100644
index 0000000..e085fed
--- /dev/null
+++ b/arch/mips/cavium-octeon/setup.c
@@ -0,0 +1,929 @@
+/*
+ * 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-2007 Cavium Networks
+ * Copyright (C) 2008 Wind River Systems
+ */
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/serial.h>
+#include <linux/types.h>
+#include <linux/string.h> /* for memset */
+#include <linux/serial.h>
+#include <linux/tty.h>
+#include <linux/time.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
+#include <linux/string.h>
+
+#include <asm/processor.h>
+#include <asm/reboot.h>
+#include <asm/smp-ops.h>
+#include <asm/system.h>
+#include <asm/irq_cpu.h>
+#include <asm/mipsregs.h>
+#include <asm/bootinfo.h>
+#include <asm/sections.h>
+#include <asm/time.h>
+
+#include <asm/octeon/octeon.h>
+
+#ifdef CONFIG_CAVIUM_DECODE_RSL
+extern void cvmx_interrupt_rsl_decode(void);
+extern int __cvmx_interrupt_ecc_report_single_bit_errors;
+extern void cvmx_interrupt_rsl_enable(void);
+#endif
+
+extern struct plat_smp_ops octeon_smp_ops;
+
+#ifdef CONFIG_PCI
+extern void pci_console_init(const char *arg);
+#endif
+
+#ifdef CONFIG_CAVIUM_RESERVE32
+extern uint64_t octeon_reserve32_memory;
+#endif
+static unsigned long long MAX_MEMORY = 512ull << 20;
+
+struct octeon_boot_descriptor *octeon_boot_desc_ptr;
+
+struct cvmx_bootinfo *octeon_bootinfo;
+EXPORT_SYMBOL(octeon_bootinfo);
+
+#ifdef CONFIG_CAVIUM_RESERVE32
+uint64_t octeon_reserve32_memory;
+EXPORT_SYMBOL(octeon_reserve32_memory);
+#endif
+
+static int octeon_uart;
+
+extern asmlinkage void handle_int(void);
+extern asmlinkage void plat_irq_dispatch(void);
+
+/**
+ * Return non zero if we are currently running in the Octeon simulator
+ *
+ * Returns
+ */
+int octeon_is_simulation(void)
+{
+ return octeon_bootinfo->board_type == CVMX_BOARD_TYPE_SIM;
+}
+EXPORT_SYMBOL(octeon_is_simulation);
+
+/**
+ * Return true if Octeon is in PCI Host mode. This means
+ * Linux can control the PCI bus.
+ *
+ * Returns Non zero if Octeon in host mode.
+ */
+int octeon_is_pci_host(void)
+{
+#ifdef CONFIG_PCI
+ return octeon_bootinfo->config_flags & CVMX_BOOTINFO_CFG_FLAG_PCI_HOST;
+#else
+ return 0;
+#endif
+}
+
+/**
+ * Get the clock rate of Octeon
+ *
+ * Returns Clock rate in HZ
+ */
+uint64_t octeon_get_clock_rate(void)
+{
+ if (octeon_is_simulation())
+ octeon_bootinfo->eclock_hz = 6000000;
+ return octeon_bootinfo->eclock_hz;
+}
+EXPORT_SYMBOL(octeon_get_clock_rate);
+
+/**
+ * Write to the LCD display connected to the bootbus. This display
+ * exists on most Cavium evaluation boards. If it doesn't exist, then
+ * this function doesn't do anything.
+ *
+ * @s: String to write
+ */
+void octeon_write_lcd(const char *s)
+{
+ if (octeon_bootinfo->led_display_base_addr) {
+ void __iomem *lcd_address =
+ ioremap_nocache(octeon_bootinfo->led_display_base_addr,
+ 8);
+ int i;
+ for (i = 0; i < 8; i++, s++) {
+ if (*s)
+ iowrite8(*s, lcd_address + i);
+ else
+ iowrite8(' ', lcd_address + i);
+ }
+ iounmap(lcd_address);
+ }
+}
+
+/**
+ * Return the console uart passed by the bootloader
+ *
+ * Returns uart (0 or 1)
+ */
+int octeon_get_boot_uart(void)
+{
+ int uart;
+#ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
+ uart = 1;
+#else
+ uart = (octeon_boot_desc_ptr->flags & OCTEON_BL_FLAG_CONSOLE_UART1) ?
+ 1 : 0;
+#endif
+ return uart;
+}
+
+/**
+ * Get the coremask Linux was booted on.
+ *
+ * Returns Core mask
+ */
+int octeon_get_boot_coremask(void)
+{
+ return octeon_boot_desc_ptr->core_mask;
+}
+
+/**
+ * Check the hardware BIST results for a CPU
+ */
+void octeon_check_cpu_bist(void)
+{
+ const int coreid = cvmx_get_core_num();
+ unsigned long long mask;
+ unsigned long long bist_val;
+
+ /* Check BIST results for COP0 registers */
+ mask = 0x1f00000000ull;
+ bist_val = read_octeon_c0_icacheerr();
+ if (bist_val & mask)
+ pr_err("Core%d BIST Failure: CacheErr(icache) = 0x%llx\n",
+ coreid, bist_val);
+
+ bist_val = read_octeon_c0_dcacheerr();
+ if (bist_val & 1)
+ pr_err("Core%d L1 Dcache parity error: "
+ "CacheErr(dcache) = 0x%llx\n",
+ coreid, bist_val);
+
+ mask = 0xfc00000000000000ull;
+ bist_val = read_c0_cvmmemctl();
+ if (bist_val & mask)
+ pr_err("Core%d BIST Failure: COP0_CVM_MEM_CTL = 0x%llx\n",
+ coreid, bist_val);
+
+ write_octeon_c0_dcacheerr(0);
+}
+
+#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
+/**
+ * Called on every core to setup the wired tlb entry needed
+ * if CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB is set.
+ *
+ */
+static void octeon_hal_setup_per_cpu_reserved32(void *unused)
+{
+ /*
+ * The config has selected to wire the reserve32 memory for all
+ * userspace applications. We need to put a wired TLB entry in for each
+ * 512MB of reserve32 memory. We only handle double 256MB pages here,
+ * so reserve32 must be multiple of 512MB.
+ */
+ uint32_t size = CONFIG_CAVIUM_RESERVE32;
+ uint32_t entrylo0 =
+ 0x7 | ((octeon_reserve32_memory & ((1ul << 40) - 1)) >> 6);
+ uint32_t entrylo1 = entrylo0 + (256 << 14);
+ uint32_t entryhi = (0x80000000UL - (CONFIG_CAVIUM_RESERVE32 << 20));
+ while (size >= 512) {
+#if 0
+ pr_info("CPU%d: Adding double wired TLB entry for 0x%lx\n",
+ smp_processor_id(), entryhi);
+#endif
+ add_wired_entry(entrylo0, entrylo1, entryhi, PM_256M);
+ entrylo0 += 512 << 14;
+ entrylo1 += 512 << 14;
+ entryhi += 512 << 20;
+ size -= 512;
+ }
+}
+#endif /* CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB */
+
+/**
+ * Called to release the named block which was used to made sure
+ * that nobody used the memory for something else during
+ * init. Now we'll free it so userspace apps can use this
+ * memory region with bootmem_alloc.
+ *
+ * This function is called only once from prom_free_prom_memory().
+ */
+void octeon_hal_setup_reserved32(void)
+{
+#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
+ on_each_cpu(octeon_hal_setup_per_cpu_reserved32, NULL, 0, 1);
+#endif
+}
+
+/**
+ * Reboot Octeon
+ *
+ * @command: Command to pass to the bootloader. Currently ignored.
+ */
+static void octeon_restart(char *command)
+{
+ /* Disable all watchdogs before soft reset. They don't get cleared */
+#ifdef CONFIG_SMP
+ int cpu;
+ for_each_online_cpu(cpu)
+ cvmx_write_csr(CVMX_CIU_WDOGX(cpu_logical_map(cpu)), 0);
+#else
+ cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0);
+#endif
+
+ mb();
+ while (1)
+ cvmx_write_csr(CVMX_CIU_SOFT_RST, 1);
+}
+
+
+/**
+ * Permanently stop a core.
+ *
+ * @arg: Ignored.
+ */
+static void octeon_kill_core(void *arg)
+{
+ mb();
+ if (octeon_is_simulation()) {
+ /* The simulator needs the watchdog to stop for dead cores */
+ cvmx_write_csr(CVMX_CIU_WDOGX(cvmx_get_core_num()), 0);
+ /* A break instruction causes the simulator stop a core */
+ asm volatile ("sync\nbreak");
+ }
+}
+
+
+/**
+ * Halt the system
+ */
+static void octeon_halt(void)
+{
+ smp_call_function(octeon_kill_core, NULL, 0);
+
+ switch (octeon_bootinfo->board_type) {
+ case CVMX_BOARD_TYPE_NAO38:
+ /* Driving a 1 to GPIO 12 shuts off this board */
+ cvmx_write_csr(CVMX_GPIO_BIT_CFGX(12), 1);
+ cvmx_write_csr(CVMX_GPIO_TX_SET, 0x1000);
+ break;
+ default:
+ octeon_write_lcd("PowerOff");
+ break;
+ }
+
+ octeon_kill_core(NULL);
+}
+
+#if 0
+/**
+ * Platform time init specifics.
+ * Returns
+ */
+void __init plat_time_init(void)
+{
+ /* Nothing special here, but we are required to have one */
+}
+
+#endif
+
+/**
+ * Handle all the error condition interrupts that might occur.
+ *
+ */
+#ifdef CONFIG_CAVIUM_DECODE_RSL
+static irqreturn_t octeon_rlm_interrupt(int cpl, void *dev_id)
+{
+ cvmx_interrupt_rsl_decode();
+ return IRQ_HANDLED;
+}
+#endif
+
+/**
+ * Return a string representing the system type
+ *
+ * Returns
+ */
+const char *octeon_board_type_string(void)
+{
+ static char name[80];
+ sprintf(name, "%s (%s)",
+ cvmx_board_type_to_string(octeon_bootinfo->board_type),
+ octeon_model_get_string(read_c0_prid()));
+ return name;
+}
+
+const char *get_system_type(void)
+ __attribute__ ((alias("octeon_board_type_string")));
+
+void octeon_user_io_init(void)
+{
+ union octeon_cvmemctl cvmmemctl;
+ union cvmx_iob_fau_timeout fau_timeout;
+ union cvmx_pow_nw_tim nm_tim;
+ uint64_t cvmctl;
+
+ /* Get the current settings for CP0_CVMMEMCTL_REG */
+ cvmmemctl.u64 = read_c0_cvmmemctl();
+ /* R/W If set, marked write-buffer entries time out the same
+ * as as other entries; if clear, marked write-buffer entries
+ * use the maximum timeout. */
+ cvmmemctl.s.dismarkwblongto = 1;
+ /* R/W If set, a merged store does not clear the write-buffer
+ * entry timeout state. */
+ cvmmemctl.s.dismrgclrwbto = 0;
+ /* R/W Two bits that are the MSBs of the resultant CVMSEG LM
+ * word location for an IOBDMA. The other 8 bits come from the
+ * SCRADDR field of the IOBDMA. */
+ cvmmemctl.s.iobdmascrmsb = 0;
+ /* R/W If set, SYNCWS and SYNCS only order marked stores; if
+ * clear, SYNCWS and SYNCS only order unmarked
+ * stores. SYNCWSMARKED has no effect when DISSYNCWS is
+ * set. */
+ cvmmemctl.s.syncwsmarked = 0;
+ /* R/W If set, SYNCWS acts as SYNCW and SYNCS acts as SYNC. */
+ cvmmemctl.s.dissyncws = 0;
+ /* R/W If set, no stall happens on write buffer full. */
+ if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2))
+ cvmmemctl.s.diswbfst = 1;
+ else
+ cvmmemctl.s.diswbfst = 0;
+ /* R/W If set (and SX set), supervisor-level loads/stores can
+ * use XKPHYS addresses with <48>==0 */
+ cvmmemctl.s.xkmemenas = 0;
+
+ /* R/W If set (and UX set), user-level loads/stores can use
+ * XKPHYS addresses with VA<48>==0 */
+ cvmmemctl.s.xkmemenau = 0;
+
+ /* R/W If set (and SX set), supervisor-level loads/stores can
+ * use XKPHYS addresses with VA<48>==1 */
+ cvmmemctl.s.xkioenas = 0;
+
+ /* R/W If set (and UX set), user-level loads/stores can use
+ * XKPHYS addresses with VA<48>==1 */
+ cvmmemctl.s.xkioenau = 0;
+
+ /* R/W If set, all stores act as SYNCW (NOMERGE must be set
+ * when this is set) RW, reset to 0. */
+ cvmmemctl.s.allsyncw = 0;
+
+ /* R/W If set, no stores merge, and all stores reach the
+ * coherent bus in order. */
+ cvmmemctl.s.nomerge = 0;
+ /* R/W Selects the bit in the counter used for DID time-outs 0
+ * = 231, 1 = 230, 2 = 229, 3 = 214. Actual time-out is
+ * between 1x and 2x this interval. For example, with
+ * DIDTTO=3, expiration interval is between 16K and 32K. */
+ cvmmemctl.s.didtto = 0;
+ /* R/W If set, the (mem) CSR clock never turns off. */
+ cvmmemctl.s.csrckalwys = 0;
+ /* R/W If set, mclk never turns off. */
+ cvmmemctl.s.mclkalwys = 0;
+ /* R/W Selects the bit in the counter used for write buffer
+ * flush time-outs (WBFLT+11) is the bit position in an
+ * internal counter used to determine expiration. The write
+ * buffer expires between 1x and 2x this interval. For
+ * example, with WBFLT = 0, a write buffer expires between 2K
+ * and 4K cycles after the write buffer entry is allocated. */
+ cvmmemctl.s.wbfltime = 0;
+ /* R/W If set, do not put Istream in the L2 cache. */
+ cvmmemctl.s.istrnol2 = 0;
+ /* R/W The write buffer threshold. */
+ cvmmemctl.s.wbthresh = 10;
+ /* R/W If set, CVMSEG is available for loads/stores in
+ * kernel/debug mode. */
+#if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
+ cvmmemctl.s.cvmsegenak = 1;
+#else
+ cvmmemctl.s.cvmsegenak = 0;
+#endif
+ /* R/W If set, CVMSEG is available for loads/stores in
+ * supervisor mode. */
+ cvmmemctl.s.cvmsegenas = 0;
+ /* R/W If set, CVMSEG is available for loads/stores in user
+ * mode. */
+ cvmmemctl.s.cvmsegenau = 0;
+ /* R/W Size of local memory in cache blocks, 54 (6912 bytes)
+ * is max legal value. */
+ cvmmemctl.s.lmemsz = CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE;
+
+
+ if (smp_processor_id() == 0)
+ pr_notice("CVMSEG size: %d cache lines (%d bytes)\n",
+ CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE,
+ CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE * 128);
+
+ write_c0_cvmmemctl(cvmmemctl.u64);
+
+ /* Move the performance counter interrupts to IRQ 6 */
+ cvmctl = read_c0_cvmctl();
+ cvmctl &= ~(7 << 7);
+ cvmctl |= 6 << 7;
+ write_c0_cvmctl(cvmctl);
+
+ /* Set a default for the hardware timeouts */
+ fau_timeout.u64 = 0;
+ fau_timeout.s.tout_val = 0xfff;
+ /* Disable tagwait FAU timeout */
+ fau_timeout.s.tout_enb = 0;
+ cvmx_write_csr(CVMX_IOB_FAU_TIMEOUT, fau_timeout.u64);
+
+ nm_tim.u64 = 0;
+ /* 4096 cycles */
+ nm_tim.s.nw_tim = 3;
+ cvmx_write_csr(CVMX_POW_NW_TIM, nm_tim.u64);
+
+ write_octeon_c0_icacheerr(0);
+ write_c0_derraddr1(0);
+}
+
+/**
+ * Early entry point for arch setup
+ */
+void __init prom_init(void)
+{
+ struct cvmx_sysinfo *sysinfo;
+ const int coreid = cvmx_get_core_num();
+ int i;
+ int argc;
+ struct uart_port octeon_port;
+#ifdef CONFIG_CAVIUM_RESERVE32
+ int64_t addr = -1;
+#endif
+ /*
+ * The bootloader passes a pointer to the boot descriptor in
+ * $a3, this is available as fw_arg3.
+ */
+ octeon_boot_desc_ptr = (struct octeon_boot_descriptor *)fw_arg3;
+ octeon_bootinfo =
+ cvmx_phys_to_ptr(octeon_boot_desc_ptr->cvmx_desc_vaddr);
+ cvmx_bootmem_init(cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr));
+
+ /*
+ * Only enable the LED controller if we're running on a CN38XX, CN58XX,
+ * or CN56XX. The CN30XX and CN31XX don't have an LED controller.
+ */
+ if (!octeon_is_simulation() &&
+ octeon_has_feature(OCTEON_FEATURE_LED_CONTROLLER)) {
+ cvmx_write_csr(CVMX_LED_EN, 0);
+ cvmx_write_csr(CVMX_LED_PRT, 0);
+ cvmx_write_csr(CVMX_LED_DBG, 0);
+ cvmx_write_csr(CVMX_LED_PRT_FMT, 0);
+ cvmx_write_csr(CVMX_LED_UDD_CNTX(0), 32);
+ cvmx_write_csr(CVMX_LED_UDD_CNTX(1), 32);
+ cvmx_write_csr(CVMX_LED_UDD_DATX(0), 0);
+ cvmx_write_csr(CVMX_LED_UDD_DATX(1), 0);
+ cvmx_write_csr(CVMX_LED_EN, 1);
+ }
+#ifdef CONFIG_CAVIUM_RESERVE32
+ /*
+ * We need to temporarily allocate all memory in the reserve32
+ * region. This makes sure the kernel doesn't allocate this
+ * memory when it is getting memory from the
+ * bootloader. Later, after the memory allocations are
+ * complete, the reserve32 will be freed.
+ */
+#ifdef CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB
+ if (CONFIG_CAVIUM_RESERVE32 & 0x1ff)
+ pr_err("CAVIUM_RESERVE32 isn't a multiple of 512MB. "
+ "This is required if CAVIUM_RESERVE32_USE_WIRED_TLB "
+ "is set\n");
+ else
+ addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
+ 0, 0, 512 << 20,
+ "CAVIUM_RESERVE32", 0);
+#else
+ /*
+ * Allocate memory for RESERVED32 aligned on 2MB boundary. This
+ * is in case we later use hugetlb entries with it.
+ */
+ addr = cvmx_bootmem_phy_named_block_alloc(CONFIG_CAVIUM_RESERVE32 << 20,
+ 0, 0, 2 << 20,
+ "CAVIUM_RESERVE32", 0);
+#endif
+ if (addr < 0)
+ pr_err("Failed to allocate CAVIUM_RESERVE32 memory area\n");
+ else
+ octeon_reserve32_memory = addr;
+#endif
+
+#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2
+ if (cvmx_read_csr(CVMX_L2D_FUS3) & (3ull << 34)) {
+ pr_info("Skipping L2 locking due to reduced L2 cache size\n");
+ } else {
+ uint32_t ebase = read_c0_ebase() & 0x3ffff000;
+#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_TLB
+ /* TLB refill */
+ cvmx_l2c_lock_mem_region(ebase, 0x100);
+#endif
+#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_EXCEPTION
+ /* General exception */
+ cvmx_l2c_lock_mem_region(ebase + 0x180, 0x80);
+#endif
+#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_LOW_LEVEL_INTERRUPT
+ /* Interrupt handler */
+ cvmx_l2c_lock_mem_region(ebase + 0x200, 0x80);
+#endif
+#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_INTERRUPT
+ cvmx_l2c_lock_mem_region(__pa_symbol(handle_int), 0x100);
+ cvmx_l2c_lock_mem_region(__pa_symbol(plat_irq_dispatch), 0x80);
+#endif
+#ifdef CONFIG_CAVIUM_OCTEON_LOCK_L2_MEMCPY
+ cvmx_l2c_lock_mem_region(__pa_symbol(memcpy), 0x480);
+#endif
+ }
+#endif
+
+ sysinfo = cvmx_sysinfo_get();
+ memset(sysinfo, 0, sizeof(*sysinfo));
+ sysinfo->system_dram_size = octeon_bootinfo->dram_size << 20;
+ sysinfo->phy_mem_desc_ptr =
+ cvmx_phys_to_ptr(octeon_bootinfo->phy_mem_desc_addr);
+ sysinfo->core_mask = octeon_bootinfo->core_mask;
+ sysinfo->exception_base_addr = octeon_bootinfo->exception_base_addr;
+ sysinfo->cpu_clock_hz = octeon_bootinfo->eclock_hz;
+ sysinfo->dram_data_rate_hz = octeon_bootinfo->dclock_hz * 2;
+ sysinfo->board_type = octeon_bootinfo->board_type;
+ sysinfo->board_rev_major = octeon_bootinfo->board_rev_major;
+ sysinfo->board_rev_minor = octeon_bootinfo->board_rev_minor;
+ memcpy(sysinfo->mac_addr_base, octeon_bootinfo->mac_addr_base,
+ sizeof(sysinfo->mac_addr_base));
+ sysinfo->mac_addr_count = octeon_bootinfo->mac_addr_count;
+ memcpy(sysinfo->board_serial_number,
+ octeon_bootinfo->board_serial_number,
+ sizeof(sysinfo->board_serial_number));
+ sysinfo->compact_flash_common_base_addr =
+ octeon_bootinfo->compact_flash_common_base_addr;
+ sysinfo->compact_flash_attribute_base_addr =
+ octeon_bootinfo->compact_flash_attribute_base_addr;
+ sysinfo->led_display_base_addr = octeon_bootinfo->led_display_base_addr;
+ sysinfo->dfa_ref_clock_hz = octeon_bootinfo->dfa_ref_clock_hz;
+ sysinfo->bootloader_config_flags = octeon_bootinfo->config_flags;
+
+
+ octeon_check_cpu_bist();
+
+ octeon_uart = octeon_get_boot_uart();
+
+ /*
+ * Disable All CIU Interrupts. The ones we need will be
+ * enabled later. Read the SUM register so we know the write
+ * completed.
+ */
+ cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), 0);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0);
+ cvmx_read_csr(CVMX_CIU_INTX_SUM0((coreid * 2)));
+
+#ifdef CONFIG_SMP
+ octeon_write_lcd("LinuxSMP");
+#else
+ octeon_write_lcd("Linux");
+#endif
+
+#ifdef CONFIG_CAVIUM_GDB
+ /*
+ * When debugging the linux kernel, force the cores to enter
+ * the debug exception handler to break in.
+ */
+ if (octeon_get_boot_debug_flag()) {
+ cvmx_write_csr(CVMX_CIU_DINT, 1 << cvmx_get_core_num());
+ cvmx_read_csr(CVMX_CIU_DINT);
+ }
+#endif
+
+ /*
+ * BIST should always be enabled when doing a soft reset. L2
+ * Cache locking for instance is not cleared unless BIST is
+ * enabled. Unfortunately due to a chip errata G-200 for
+ * Cn38XX and CN31XX, BIST msut be disabled on these parts.
+ */
+ if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS2) ||
+ OCTEON_IS_MODEL(OCTEON_CN31XX))
+ cvmx_write_csr(CVMX_CIU_SOFT_BIST, 0);
+ else
+ cvmx_write_csr(CVMX_CIU_SOFT_BIST, 1);
+
+ /* Default to 64MB in the simulator to speed things up */
+ if (octeon_is_simulation())
+ MAX_MEMORY = 64ull << 20;
+
+ arcs_cmdline[0] = 0;
+ argc = octeon_boot_desc_ptr->argc;
+ for (i = 0; i < argc; i++) {
+ const char *arg =
+ cvmx_phys_to_ptr(octeon_boot_desc_ptr->argv[i]);
+ if ((strncmp(arg, "MEM=", 4) == 0) ||
+ (strncmp(arg, "mem=", 4) == 0)) {
+ sscanf(arg + 4, "%llu", &MAX_MEMORY);
+ MAX_MEMORY <<= 20;
+ if (MAX_MEMORY == 0)
+ MAX_MEMORY = 32ull << 30;
+ } else if (strcmp(arg, "ecc_verbose") == 0) {
+#ifdef CONFIG_CAVIUM_REPORT_SINGLE_BIT_ECC
+ __cvmx_interrupt_ecc_report_single_bit_errors = 1;
+ pr_notice("Reporting of single bit ECC errors is "
+ "turned on\n");
+#endif
+ } else if (strlen(arcs_cmdline) + strlen(arg) + 1 <
+ sizeof(arcs_cmdline) - 1) {
+ strcat(arcs_cmdline, " ");
+ strcat(arcs_cmdline, arg);
+ }
+ }
+
+ if (strstr(arcs_cmdline, "console=") == NULL) {
+#ifdef CONFIG_GDB_CONSOLE
+ strcat(arcs_cmdline, " console=gdb");
+#else
+#ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
+ strcat(arcs_cmdline, " console=ttyS0,115200");
+#else
+ if (octeon_uart == 1)
+ strcat(arcs_cmdline, " console=ttyS1,115200");
+ else
+ strcat(arcs_cmdline, " console=ttyS0,115200");
+#endif
+#endif
+ }
+
+ if (octeon_is_simulation()) {
+ /*
+ * The simulator uses a mtdram device pre filled with
+ * the filesystem. Also specify the calibration delay
+ * to avoid calculating it every time.
+ */
+ strcat(arcs_cmdline, " rw root=1f00"
+ " lpj=60176 slram=root,0x40000000,+1073741824");
+ }
+
+ mips_hpt_frequency = octeon_get_clock_rate();
+
+ octeon_init_cvmcount();
+
+ _machine_restart = octeon_restart;
+ _machine_halt = octeon_halt;
+
+ memset(&octeon_port, 0, sizeof(octeon_port));
+ /*
+ * For early_serial_setup we don't set the port type or
+ * UPF_FIXED_TYPE.
+ */
+ octeon_port.flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ;
+ octeon_port.iotype = UPIO_MEM;
+ /* I/O addresses are every 8 bytes */
+ octeon_port.regshift = 3;
+ /* Clock rate of the chip */
+ octeon_port.uartclk = mips_hpt_frequency;
+ octeon_port.fifosize = 64;
+ octeon_port.mapbase = 0x0001180000000800ull + (1024 * octeon_uart);
+ octeon_port.membase = cvmx_phys_to_ptr(octeon_port.mapbase);
+ octeon_port.serial_in = octeon_serial_in;
+ octeon_port.serial_out = octeon_serial_out;
+#ifdef CONFIG_CAVIUM_OCTEON_2ND_KERNEL
+ octeon_port.line = 0;
+#else
+ octeon_port.line = octeon_uart;
+#endif
+ octeon_port.irq = 42 + octeon_uart;
+ early_serial_setup(&octeon_port);
+
+ octeon_user_io_init();
+ register_smp_ops(&octeon_smp_ops);
+}
+
+void __init plat_mem_setup(void)
+{
+ uint64_t mem_alloc_size;
+ uint64_t total;
+ int64_t memory;
+
+ total = 0;
+
+ /* First add the init memory we will be returning. */
+ memory = __pa_symbol(&__init_begin) & PAGE_MASK;
+ mem_alloc_size = (__pa_symbol(&__init_end) & PAGE_MASK) - memory;
+ if (mem_alloc_size > 0) {
+ add_memory_region(memory, mem_alloc_size, BOOT_MEM_RAM);
+ total += mem_alloc_size;
+ }
+
+ /*
+ * The Mips memory init uses the first memory location for
+ * some memory vectors. When SPARSEMEM is in use, it doesn't
+ * verify that the size is big enough for the final
+ * vectors. Making the smallest chuck 4MB seems to be enough
+ * to consistantly work.
+ */
+ mem_alloc_size = 4 << 20;
+ if (mem_alloc_size > MAX_MEMORY)
+ mem_alloc_size = MAX_MEMORY;
+
+ /*
+ * When allocating memory, we want incrementing addresses from
+ * bootmem_alloc so the code in add_memory_region can merge
+ * regions next to each other.
+ */
+ cvmx_bootmem_lock();
+ while ((boot_mem_map.nr_map < BOOT_MEM_MAP_MAX)
+ && (total < MAX_MEMORY)) {
+#if defined(CONFIG_64BIT) || defined(CONFIG_64BIT_PHYS_ADDR)
+ memory = cvmx_bootmem_phy_alloc(mem_alloc_size,
+ __pa_symbol(&__init_end), -1,
+ 0x100000,
+ CVMX_BOOTMEM_FLAG_NO_LOCKING);
+#elif defined(CONFIG_HIGHMEM)
+ memory = cvmx_bootmem_phy_alloc(mem_alloc_size, 0, 1ull << 31,
+ 0x100000,
+ CVMX_BOOTMEM_FLAG_NO_LOCKING);
+#else
+ memory = cvmx_bootmem_phy_alloc(mem_alloc_size, 0, 512 << 20,
+ 0x100000,
+ CVMX_BOOTMEM_FLAG_NO_LOCKING);
+#endif
+ if (memory >= 0) {
+ /*
+ * This function automatically merges address
+ * regions next to each other if they are
+ * received in incrementing order.
+ */
+ add_memory_region(memory, mem_alloc_size, BOOT_MEM_RAM);
+ total += mem_alloc_size;
+ } else {
+ break;
+ }
+ }
+ cvmx_bootmem_unlock();
+
+#ifdef CONFIG_CAVIUM_RESERVE32
+ /*
+ * Now that we've allocated the kernel memory it is safe to
+ * free the reserved region. We free it here so that builtin
+ * drivers can use the memory.
+ */
+ if (octeon_reserve32_memory)
+ cvmx_bootmem_free_named("CAVIUM_RESERVE32");
+#endif /* CONFIG_CAVIUM_RESERVE32 */
+
+ if (total == 0)
+ panic("Unable to allocate memory from "
+ "cvmx_bootmem_phy_alloc\n");
+}
+
+
+int prom_putchar(char c)
+{
+ uint64_t lsrval;
+
+ /* Spin until there is room */
+ do {
+ lsrval = cvmx_read_csr(CVMX_MIO_UARTX_LSR(octeon_uart));
+ } while ((lsrval & 0x20) == 0);
+
+ /* Write the byte */
+ cvmx_write_csr(CVMX_MIO_UARTX_THR(octeon_uart), c);
+ return 1;
+}
+
+void prom_free_prom_memory(void)
+{
+#ifdef CONFIG_CAVIUM_DECODE_RSL
+ cvmx_interrupt_rsl_enable();
+
+ /* Add an interrupt handler for general failures. */
+ if (request_irq(OCTEON_IRQ_RML, octeon_rlm_interrupt, IRQF_SHARED,
+ "RML/RSL", octeon_rlm_interrupt)) {
+ panic("Unable to request_irq(OCTEON_IRQ_RML)\n");
+ }
+#endif
+
+ /* This call is here so that it is performed after any TLB
+ initializations. It needs to be after these in case the
+ CONFIG_CAVIUM_RESERVE32_USE_WIRED_TLB option is set */
+ octeon_hal_setup_reserved32();
+}
+
+static struct octeon_cf_data octeon_cf_data;
+
+static int __init octeon_cf_device_init(void)
+{
+ union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg;
+ unsigned long base_ptr, region_base, region_size;
+ struct platform_device *pd;
+ struct resource cf_resources[3];
+ unsigned int num_resources;
+ int i;
+ int ret = 0;
+
+ /* Setup octeon-cf platform device if present. */
+ base_ptr = 0;
+ if (octeon_bootinfo->major_version == 1
+ && octeon_bootinfo->minor_version >= 1) {
+ if (octeon_bootinfo->compact_flash_common_base_addr)
+ base_ptr =
+ octeon_bootinfo->compact_flash_common_base_addr;
+ } else {
+ base_ptr = 0x1d000800;
+ }
+
+ if (!base_ptr)
+ return ret;
+
+ /* Find CS0 region. */
+ for (i = 0; i < 8; i++) {
+ mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i));
+ region_base = mio_boot_reg_cfg.s.base << 16;
+ region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
+ if (mio_boot_reg_cfg.s.en && base_ptr >= region_base
+ && base_ptr < region_base + region_size)
+ break;
+ }
+ if (i >= 7) {
+ /* i and i + 1 are CS0 and CS1, both must be less than 8. */
+ goto out;
+ }
+ octeon_cf_data.base_region = i;
+ octeon_cf_data.is16bit = mio_boot_reg_cfg.s.width;
+ octeon_cf_data.base_region_bias = base_ptr - region_base;
+ memset(cf_resources, 0, sizeof(cf_resources));
+ num_resources = 0;
+ cf_resources[num_resources].flags = IORESOURCE_MEM;
+ cf_resources[num_resources].start = region_base;
+ cf_resources[num_resources].end = region_base + region_size - 1;
+ num_resources++;
+
+
+ if (!(base_ptr & 0xfffful)) {
+ /*
+ * Boot loader signals availability of DMA (true_ide
+ * mode) by setting low order bits of base_ptr to
+ * zero.
+ */
+
+ /* Asume that CS1 immediately follows. */
+ mio_boot_reg_cfg.u64 =
+ cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(i + 1));
+ region_base = mio_boot_reg_cfg.s.base << 16;
+ region_size = (mio_boot_reg_cfg.s.size + 1) << 16;
+ if (!mio_boot_reg_cfg.s.en)
+ goto out;
+
+ cf_resources[num_resources].flags = IORESOURCE_MEM;
+ cf_resources[num_resources].start = region_base;
+ cf_resources[num_resources].end = region_base + region_size - 1;
+ num_resources++;
+
+ octeon_cf_data.dma_engine = 0;
+ cf_resources[num_resources].flags = IORESOURCE_IRQ;
+ cf_resources[num_resources].start = OCTEON_IRQ_BOOTDMA;
+ cf_resources[num_resources].end = OCTEON_IRQ_BOOTDMA;
+ num_resources++;
+ } else {
+ octeon_cf_data.dma_engine = -1;
+ }
+
+ pd = platform_device_alloc("pata_octeon_cf", -1);
+ if (!pd) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ pd->dev.platform_data = &octeon_cf_data;
+
+ ret = platform_device_add_resources(pd, cf_resources, num_resources);
+ if (ret)
+ goto fail;
+
+ ret = platform_device_add(pd);
+ if (ret)
+ goto fail;
+
+ return ret;
+fail:
+ platform_device_put(pd);
+out:
+ return ret;
+}
+device_initcall(octeon_cf_device_init);
diff --git a/arch/mips/cavium-octeon/smp.c b/arch/mips/cavium-octeon/smp.c
new file mode 100644
index 0000000..24e0ad6
--- /dev/null
+++ b/arch/mips/cavium-octeon/smp.c
@@ -0,0 +1,211 @@
+/*
+ * 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-2008 Cavium Networks
+ */
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/kernel_stat.h>
+#include <linux/sched.h>
+#include <linux/module.h>
+
+#include <asm/mmu_context.h>
+#include <asm/system.h>
+#include <asm/time.h>
+
+#include <asm/octeon/octeon.h>
+
+volatile unsigned long octeon_processor_boot = 0xff;
+volatile unsigned long octeon_processor_sp;
+volatile unsigned long octeon_processor_gp;
+
+static irqreturn_t mailbox_interrupt(int irq, void *dev_id)
+{
+ const int coreid = cvmx_get_core_num();
+ uint64_t action;
+
+ /* Load the mailbox register to figure out what we're supposed to do */
+ action = cvmx_read_csr(CVMX_CIU_MBOX_CLRX(coreid));
+
+ /* Clear the mailbox to clear the interrupt */
+ cvmx_write_csr(CVMX_CIU_MBOX_CLRX(coreid), action);
+
+ if (action & SMP_CALL_FUNCTION)
+ smp_call_function_interrupt();
+
+ /* Check if we've been told to flush the icache */
+ if (action & SMP_ICACHE_FLUSH)
+ asm volatile ("synci 0($0)\n");
+ return IRQ_HANDLED;
+}
+
+/**
+ * Cause the function described by call_data to be executed on the passed
+ * cpu. When the function has finished, increment the finished field of
+ * call_data.
+ */
+void octeon_send_ipi_single(int cpu, unsigned int action)
+{
+ int coreid = cpu_logical_map(cpu);
+ /*
+ pr_info("SMP: Mailbox send cpu=%d, coreid=%d, action=%u\n", cpu,
+ coreid, action);
+ */
+ cvmx_write_csr(CVMX_CIU_MBOX_SETX(coreid), action);
+}
+
+static inline void octeon_send_ipi_mask(cpumask_t mask, unsigned int action)
+{
+ unsigned int i;
+
+ for_each_cpu_mask(i, mask)
+ octeon_send_ipi_single(i, action);
+}
+
+/**
+ * Detect available CPUs, populate phys_cpu_present_map
+ */
+static void octeon_smp_setup(void)
+{
+ const int coreid = cvmx_get_core_num();
+ int cpus;
+ int id;
+
+ int core_mask = octeon_get_boot_coremask();
+
+ cpus_clear(cpu_possible_map);
+ __cpu_number_map[coreid] = 0;
+ __cpu_logical_map[0] = coreid;
+ cpu_set(0, cpu_possible_map);
+
+ cpus = 1;
+ for (id = 0; id < 16; id++) {
+ if ((id != coreid) && (core_mask & (1 << id))) {
+ cpu_set(cpus, cpu_possible_map);
+ __cpu_number_map[id] = cpus;
+ __cpu_logical_map[cpus] = id;
+ cpus++;
+ }
+ }
+}
+
+/**
+ * Firmware CPU startup hook
+ *
+ */
+static void octeon_boot_secondary(int cpu, struct task_struct *idle)
+{
+ int count;
+
+ pr_info("SMP: Booting CPU%02d (CoreId %2d)...\n", cpu,
+ cpu_logical_map(cpu));
+
+ octeon_processor_sp = __KSTK_TOS(idle);
+ octeon_processor_gp = (unsigned long)(task_thread_info(idle));
+ octeon_processor_boot = cpu_logical_map(cpu);
+ mb();
+
+ count = 10000;
+ while (octeon_processor_sp && count) {
+ /* Waiting for processor to get the SP and GP */
+ udelay(1);
+ count--;
+ }
+ if (count == 0)
+ pr_err("Secondary boot timeout\n");
+}
+
+/**
+ * After we've done initial boot, this function is called to allow the
+ * board code to clean up state, if needed
+ */
+static void octeon_init_secondary(void)
+{
+ const int coreid = cvmx_get_core_num();
+ union cvmx_ciu_intx_sum0 interrupt_enable;
+
+ octeon_check_cpu_bist();
+ octeon_init_cvmcount();
+ /*
+ pr_info("SMP: CPU%d (CoreId %lu) started\n", cpu, coreid);
+ */
+ /* Enable Mailbox interrupts to this core. These are the only
+ interrupts allowed on line 3 */
+ cvmx_write_csr(CVMX_CIU_MBOX_CLRX(coreid), 0xffffffff);
+ interrupt_enable.u64 = 0;
+ interrupt_enable.s.mbox = 0x3;
+ cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2)), interrupt_enable.u64);
+ cvmx_write_csr(CVMX_CIU_INTX_EN0((coreid * 2 + 1)), 0);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2)), 0);
+ cvmx_write_csr(CVMX_CIU_INTX_EN1((coreid * 2 + 1)), 0);
+ /* Enable core interrupt processing for 2,3 and 7 */
+ set_c0_status(0x8c01);
+}
+
+/**
+ * Callout to firmware before smp_init
+ *
+ */
+void octeon_prepare_cpus(unsigned int max_cpus)
+{
+ cvmx_write_csr(CVMX_CIU_MBOX_CLRX(cvmx_get_core_num()), 0xffffffff);
+ if (request_irq(OCTEON_IRQ_MBOX0, mailbox_interrupt, IRQF_SHARED,
+ "mailbox0", mailbox_interrupt)) {
+ panic("Cannot request_irq(OCTEON_IRQ_MBOX0)\n");
+ }
+ if (request_irq(OCTEON_IRQ_MBOX1, mailbox_interrupt, IRQF_SHARED,
+ "mailbox1", mailbox_interrupt)) {
+ panic("Cannot request_irq(OCTEON_IRQ_MBOX1)\n");
+ }
+}
+
+/**
+ * Last chance for the board code to finish SMP initialization before
+ * the CPU is "online".
+ */
+static void octeon_smp_finish(void)
+{
+#ifdef CONFIG_CAVIUM_GDB
+ unsigned long tmp;
+ /* Pulse MCD0 signal on Ctrl-C to stop all the cores. Also set the MCD0
+ to be not masked by this core so we know the signal is received by
+ someone */
+ asm volatile ("dmfc0 %0, $22\n"
+ "ori %0, %0, 0x9100\n" "dmtc0 %0, $22\n" : "=r" (tmp));
+#endif
+
+ octeon_user_io_init();
+
+ /* to generate the first CPU timer interrupt */
+ write_c0_compare(read_c0_count() + mips_hpt_frequency / HZ);
+}
+
+/**
+ * Hook for after all CPUs are online
+ */
+static void octeon_cpus_done(void)
+{
+#ifdef CONFIG_CAVIUM_GDB
+ unsigned long tmp;
+ /* Pulse MCD0 signal on Ctrl-C to stop all the cores. Also set the MCD0
+ to be not masked by this core so we know the signal is received by
+ someone */
+ asm volatile ("dmfc0 %0, $22\n"
+ "ori %0, %0, 0x9100\n" "dmtc0 %0, $22\n" : "=r" (tmp));
+#endif
+}
+
+struct plat_smp_ops octeon_smp_ops = {
+ .send_ipi_single = octeon_send_ipi_single,
+ .send_ipi_mask = octeon_send_ipi_mask,
+ .init_secondary = octeon_init_secondary,
+ .smp_finish = octeon_smp_finish,
+ .cpus_done = octeon_cpus_done,
+ .boot_secondary = octeon_boot_secondary,
+ .smp_setup = octeon_smp_setup,
+ .prepare_cpus = octeon_prepare_cpus,
+};
diff --git a/arch/mips/configs/cavium-octeon_defconfig b/arch/mips/configs/cavium-octeon_defconfig
new file mode 100644
index 0000000..7afaa28
--- /dev/null
+++ b/arch/mips/configs/cavium-octeon_defconfig
@@ -0,0 +1,943 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.28-rc6
+# Wed Dec 3 11:00:58 2008
+#
+CONFIG_MIPS=y
+
+#
+# Machine selection
+#
+# CONFIG_MACH_ALCHEMY is not set
+# CONFIG_BASLER_EXCITE is not set
+# CONFIG_BCM47XX is not set
+# CONFIG_MIPS_COBALT is not set
+# CONFIG_MACH_DECSTATION is not set
+# CONFIG_MACH_JAZZ is not set
+# CONFIG_LASAT is not set
+# CONFIG_LEMOTE_FULONG is not set
+# CONFIG_MIPS_MALTA is not set
+# CONFIG_MIPS_SIM is not set
+# CONFIG_MACH_EMMA is not set
+# CONFIG_MACH_VR41XX is not set
+# CONFIG_NXP_STB220 is not set
+# CONFIG_NXP_STB225 is not set
+# CONFIG_PNX8550_JBS is not set
+# CONFIG_PNX8550_STB810 is not set
+# CONFIG_PMC_MSP is not set
+# CONFIG_PMC_YOSEMITE is not set
+# CONFIG_SGI_IP22 is not set
+# CONFIG_SGI_IP27 is not set
+# CONFIG_SGI_IP28 is not set
+# CONFIG_SGI_IP32 is not set
+# CONFIG_SIBYTE_CRHINE is not set
+# CONFIG_SIBYTE_CARMEL is not set
+# CONFIG_SIBYTE_CRHONE is not set
+# CONFIG_SIBYTE_RHONE is not set
+# CONFIG_SIBYTE_SWARM is not set
+# CONFIG_SIBYTE_LITTLESUR is not set
+# CONFIG_SIBYTE_SENTOSA is not set
+# CONFIG_SIBYTE_BIGSUR is not set
+# CONFIG_SNI_RM is not set
+# CONFIG_MACH_TX39XX is not set
+# CONFIG_MACH_TX49XX is not set
+# CONFIG_MIKROTIK_RB532 is not set
+# CONFIG_WR_PPMC is not set
+# CONFIG_CAVIUM_OCTEON_SIMULATOR is not set
+CONFIG_CAVIUM_OCTEON_REFERENCE_BOARD=y
+CONFIG_CAVIUM_OCTEON_SPECIFIC_OPTIONS=y
+# CONFIG_CAVIUM_OCTEON_2ND_KERNEL is not set
+CONFIG_CAVIUM_OCTEON_HW_FIX_UNALIGNED=y
+CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE=2
+CONFIG_CAVIUM_OCTEON_LOCK_L2=y
+CONFIG_CAVIUM_OCTEON_LOCK_L2_TLB=y
+CONFIG_CAVIUM_OCTEON_LOCK_L2_EXCEPTION=y
+CONFIG_CAVIUM_OCTEON_LOCK_L2_LOW_LEVEL_INTERRUPT=y
+CONFIG_CAVIUM_OCTEON_LOCK_L2_INTERRUPT=y
+CONFIG_CAVIUM_OCTEON_LOCK_L2_MEMCPY=y
+CONFIG_ARCH_SPARSEMEM_ENABLE=y
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_ARCH_HAS_ILOG2_U32 is not set
+# CONFIG_ARCH_HAS_ILOG2_U64 is not set
+CONFIG_ARCH_SUPPORTS_OPROFILE=y
+CONFIG_GENERIC_FIND_NEXT_BIT=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CMOS_UPDATE=y
+CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
+# CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ is not set
+CONFIG_CEVT_R4K=y
+CONFIG_CSRC_R4K=y
+CONFIG_DMA_COHERENT=y
+# CONFIG_EARLY_PRINTK is not set
+CONFIG_SYS_HAS_EARLY_PRINTK=y
+# CONFIG_HOTPLUG_CPU is not set
+# CONFIG_NO_IOPORT is not set
+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_OCTEON=y
+CONFIG_SWAP_IO_SPACE=y
+CONFIG_MIPS_L1_CACHE_SHIFT=7
+
+#
+# CPU selection
+#
+# CONFIG_CPU_LOONGSON2 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
+# CONFIG_CPU_R4300 is not set
+# CONFIG_CPU_R4X00 is not set
+# CONFIG_CPU_TX49XX is not set
+# CONFIG_CPU_R5000 is not set
+# CONFIG_CPU_R5432 is not set
+# CONFIG_CPU_R5500 is not set
+# CONFIG_CPU_R6000 is not set
+# CONFIG_CPU_NEVADA is not set
+# CONFIG_CPU_R8000 is not set
+# CONFIG_CPU_R10000 is not set
+# CONFIG_CPU_RM7000 is not set
+# CONFIG_CPU_RM9000 is not set
+# CONFIG_CPU_SB1 is not set
+CONFIG_CPU_CAVIUM_OCTEON=y
+CONFIG_WEAK_ORDERING=y
+CONFIG_WEAK_REORDERING_BEYOND_LLSC=y
+CONFIG_CPU_MIPSR2=y
+CONFIG_SYS_SUPPORTS_64BIT_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_DISABLED=y
+# CONFIG_MIPS_MT_SMP is not set
+# CONFIG_MIPS_MT_SMTC is not set
+CONFIG_64BIT_PHYS_ADDR=y
+CONFIG_CPU_HAS_SYNC=y
+CONFIG_GENERIC_HARDIRQS=y
+CONFIG_GENERIC_IRQ_PROBE=y
+CONFIG_IRQ_PER_CPU=y
+CONFIG_CPU_SUPPORTS_HIGHMEM=y
+CONFIG_SYS_SUPPORTS_HIGHMEM=y
+CONFIG_ARCH_FLATMEM_ENABLE=y
+CONFIG_ARCH_POPULATES_NODE_MAP=y
+CONFIG_SELECT_MEMORY_MODEL=y
+# CONFIG_FLATMEM_MANUAL is not set
+# CONFIG_DISCONTIGMEM_MANUAL is not set
+CONFIG_SPARSEMEM_MANUAL=y
+CONFIG_SPARSEMEM=y
+CONFIG_HAVE_MEMORY_PRESENT=y
+CONFIG_SPARSEMEM_STATIC=y
+CONFIG_PAGEFLAGS_EXTENDED=y
+CONFIG_SPLIT_PTLOCK_CPUS=4
+CONFIG_RESOURCES_64BIT=y
+CONFIG_PHYS_ADDR_T_64BIT=y
+CONFIG_ZONE_DMA_FLAG=0
+CONFIG_VIRT_TO_BUS=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_SMP=y
+CONFIG_SYS_SUPPORTS_SMP=y
+CONFIG_NR_CPUS_DEFAULT_16=y
+CONFIG_NR_CPUS=16
+# CONFIG_NO_HZ is not set
+# CONFIG_HIGH_RES_TIMERS is not set
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+# CONFIG_HZ_48 is not set
+# CONFIG_HZ_100 is not set
+# CONFIG_HZ_128 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_256 is not set
+# CONFIG_HZ_1000 is not set
+# CONFIG_HZ_1024 is not set
+CONFIG_SYS_SUPPORTS_ARBIT_HZ=y
+CONFIG_HZ=250
+# CONFIG_PREEMPT_NONE is not set
+# CONFIG_PREEMPT_VOLUNTARY is not set
+CONFIG_PREEMPT=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_KEXEC is not set
+CONFIG_SECCOMP=y
+CONFIG_LOCKDEP_SUPPORT=y
+CONFIG_STACKTRACE_SUPPORT=y
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_LOCK_KERNEL=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_LOCALVERSION=""
+CONFIG_LOCALVERSION_AUTO=y
+CONFIG_SWAP=y
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_GROUP_SCHED=y
+CONFIG_FAIR_GROUP_SCHED=y
+# CONFIG_RT_GROUP_SCHED is not set
+CONFIG_USER_SCHED=y
+# CONFIG_CGROUP_SCHED is not set
+CONFIG_SYSFS_DEPRECATED=y
+CONFIG_SYSFS_DEPRECATED_V2=y
+CONFIG_RELAY=y
+# CONFIG_NAMESPACES is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
+CONFIG_SYSCTL=y
+CONFIG_EMBEDDED=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_ALL is not set
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+# CONFIG_PCSPKR_PLATFORM is not set
+CONFIG_COMPAT_BRK=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_ANON_INODES=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_SHMEM=y
+CONFIG_AIO=y
+CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_SLAB=y
+# CONFIG_SLUB is not set
+# CONFIG_SLOB is not set
+# CONFIG_PROFILING is not set
+# CONFIG_MARKERS is not set
+CONFIG_HAVE_OPROFILE=y
+CONFIG_USE_GENERIC_SMP_HELPERS=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_SLABINFO=y
+CONFIG_RT_MUTEXES=y
+# CONFIG_TINY_SHMEM is not set
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
+CONFIG_MODULE_UNLOAD=y
+# CONFIG_MODULE_FORCE_UNLOAD is not set
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_KMOD=y
+CONFIG_STOP_MACHINE=y
+CONFIG_BLOCK=y
+# CONFIG_BLK_DEV_IO_TRACE is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
+CONFIG_BLOCK_COMPAT=y
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_AS=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_AS is not set
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+CONFIG_CLASSIC_RCU=y
+# CONFIG_PROBE_INITRD_HEADER is not set
+# CONFIG_FREEZER is not set
+
+#
+# Bus options (PCI, PCMCIA, EISA, ISA, TC)
+#
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_MMU=y
+# CONFIG_PCCARD is not set
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+CONFIG_MIPS32_COMPAT=y
+CONFIG_COMPAT=y
+CONFIG_SYSVIPC_COMPAT=y
+CONFIG_MIPS32_O32=y
+CONFIG_MIPS32_N32=y
+CONFIG_BINFMT_ELF32=y
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_PACKET_MMAP=y
+CONFIG_UNIX=y
+CONFIG_XFRM=y
+# CONFIG_XFRM_USER is not set
+# CONFIG_XFRM_SUB_POLICY is not set
+# CONFIG_XFRM_MIGRATE is not set
+# CONFIG_XFRM_STATISTICS is not set
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+CONFIG_IP_ADVANCED_ROUTER=y
+CONFIG_ASK_IP_FIB_HASH=y
+# CONFIG_IP_FIB_TRIE is not set
+CONFIG_IP_FIB_HASH=y
+CONFIG_IP_MULTIPLE_TABLES=y
+CONFIG_IP_ROUTE_MULTIPATH=y
+CONFIG_IP_ROUTE_VERBOSE=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP 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_XFRM_TUNNEL is not set
+# CONFIG_INET_TUNNEL is not set
+CONFIG_INET_XFRM_MODE_TRANSPORT=y
+CONFIG_INET_XFRM_MODE_TUNNEL=y
+CONFIG_INET_XFRM_MODE_BEET=y
+# CONFIG_INET_LRO is not set
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# CONFIG_TCP_CONG_ADVANCED is not set
+CONFIG_TCP_CONG_CUBIC=y
+CONFIG_DEFAULT_TCP_CONG="cubic"
+# CONFIG_TCP_MD5SIG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_NETLABEL is not set
+# CONFIG_NETWORK_SECMARK is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
+# CONFIG_VLAN_8021Q is not set
+# CONFIG_DECNET is not set
+# CONFIG_LLC2 is not set
+# CONFIG_IPX is not set
+# CONFIG_ATALK is not set
+# CONFIG_X25 is not set
+# CONFIG_LAPB is not set
+# CONFIG_ECONET is not set
+# CONFIG_WAN_ROUTER is not set
+# CONFIG_NET_SCHED is not set
+
+#
+# Network testing
+#
+# CONFIG_NET_PKTGEN is not set
+# CONFIG_HAMRADIO is not set
+# CONFIG_CAN is not set
+# CONFIG_IRDA is not set
+# CONFIG_BT is not set
+# CONFIG_AF_RXRPC is not set
+# CONFIG_PHONET is not set
+CONFIG_FIB_RULES=y
+# CONFIG_WIRELESS is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+# CONFIG_FW_LOADER is not set
+# CONFIG_DEBUG_DRIVER is not set
+# CONFIG_DEBUG_DEVRES is not set
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_CONCAT is not set
+CONFIG_MTD_PARTITIONS=y
+# CONFIG_MTD_REDBOOT_PARTS is not set
+# CONFIG_MTD_CMDLINE_PARTS is not set
+# CONFIG_MTD_AR7_PARTS is not set
+
+#
+# User Modules And Translation Layers
+#
+CONFIG_MTD_CHAR=y
+CONFIG_MTD_BLKDEVS=y
+CONFIG_MTD_BLOCK=y
+# CONFIG_FTL is not set
+# CONFIG_NFTL is not set
+# CONFIG_INFTL is not set
+# CONFIG_RFD_FTL is not set
+# CONFIG_SSFDC is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=y
+# CONFIG_MTD_JEDECPROBE is not set
+CONFIG_MTD_GEN_PROBE=y
+# CONFIG_MTD_CFI_ADV_OPTIONS is not set
+CONFIG_MTD_MAP_BANK_WIDTH_1=y
+CONFIG_MTD_MAP_BANK_WIDTH_2=y
+CONFIG_MTD_MAP_BANK_WIDTH_4=y
+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
+CONFIG_MTD_CFI_I1=y
+CONFIG_MTD_CFI_I2=y
+# CONFIG_MTD_CFI_I4 is not set
+# CONFIG_MTD_CFI_I8 is not set
+# CONFIG_MTD_CFI_INTELEXT is not set
+CONFIG_MTD_CFI_AMDSTD=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+# CONFIG_MTD_RAM is not set
+# CONFIG_MTD_ROM is not set
+# CONFIG_MTD_ABSENT is not set
+
+#
+# Mapping drivers for chip access
+#
+# CONFIG_MTD_COMPLEX_MAPPINGS is not set
+CONFIG_MTD_PHYSMAP=y
+CONFIG_MTD_PHYSMAP_START=0x8000000
+CONFIG_MTD_PHYSMAP_LEN=0x0
+CONFIG_MTD_PHYSMAP_BANKWIDTH=2
+# CONFIG_MTD_PLATRAM is not set
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+# CONFIG_MTD_MTDRAM is not set
+# CONFIG_MTD_BLOCK2MTD is not set
+
+#
+# Disk-On-Chip Device Drivers
+#
+# CONFIG_MTD_DOC2000 is not set
+# CONFIG_MTD_DOC2001 is not set
+# CONFIG_MTD_DOC2001PLUS is not set
+# CONFIG_MTD_NAND is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# UBI - Unsorted block images
+#
+# CONFIG_MTD_UBI is not set
+# CONFIG_PARPORT is not set
+CONFIG_BLK_DEV=y
+# CONFIG_BLK_DEV_COW_COMMON is not set
+CONFIG_BLK_DEV_LOOP=y
+# CONFIG_BLK_DEV_CRYPTOLOOP is not set
+# CONFIG_BLK_DEV_NBD is not set
+# CONFIG_BLK_DEV_RAM is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
+# CONFIG_MISC_DEVICES is not set
+CONFIG_HAVE_IDE=y
+# CONFIG_IDE is not set
+
+#
+# SCSI device support
+#
+# CONFIG_RAID_ATTRS is not set
+# CONFIG_SCSI is not set
+# CONFIG_SCSI_DMA is not set
+# CONFIG_SCSI_NETLINK is not set
+# CONFIG_ATA is not set
+# CONFIG_MD is not set
+CONFIG_NETDEVICES=y
+# CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
+# CONFIG_MACVLAN is not set
+# CONFIG_EQUALIZER is not set
+# CONFIG_TUN is not set
+# CONFIG_VETH is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+CONFIG_MII=y
+# CONFIG_AX88796 is not set
+# CONFIG_SMC91X is not set
+# CONFIG_DM9000 is not set
+# CONFIG_IBM_NEW_EMAC_ZMII is not set
+# CONFIG_IBM_NEW_EMAC_RGMII is not set
+# CONFIG_IBM_NEW_EMAC_TAH is not set
+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
+# CONFIG_B44 is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_NETDEV_10000 is not set
+
+#
+# Wireless LAN
+#
+# CONFIG_WLAN_PRE80211 is not set
+# CONFIG_WLAN_80211 is not set
+# CONFIG_IWLWIFI_LEDS is not set
+# CONFIG_WAN is not set
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+# CONFIG_NETCONSOLE is not set
+# CONFIG_NETPOLL is not set
+# CONFIG_NET_POLL_CONTROLLER is not set
+# CONFIG_ISDN is not set
+# CONFIG_PHONE is not set
+
+#
+# Input device support
+#
+# CONFIG_INPUT is not set
+
+#
+# Hardware I/O ports
+#
+# CONFIG_SERIO is not set
+# CONFIG_GAMEPORT is not set
+
+#
+# Character devices
+#
+# CONFIG_VT is not set
+CONFIG_DEVKMEM=y
+# CONFIG_SERIAL_NONSTANDARD is not set
+
+#
+# Serial drivers
+#
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_NR_UARTS=2
+CONFIG_SERIAL_8250_RUNTIME_UARTS=2
+# CONFIG_SERIAL_8250_EXTENDED is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+CONFIG_SERIAL_CORE_CONSOLE=y
+CONFIG_UNIX98_PTYS=y
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_IPMI_HANDLER is not set
+# CONFIG_HW_RANDOM is not set
+# CONFIG_R3964 is not set
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+
+#
+# Multifunction device drivers
+#
+# CONFIG_MFD_CORE is not set
+# CONFIG_MFD_SM501 is not set
+# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
+
+#
+# Multimedia devices
+#
+
+#
+# Multimedia core support
+#
+# CONFIG_VIDEO_DEV is not set
+# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
+# CONFIG_DAB is not set
+
+#
+# Graphics support
+#
+# CONFIG_VGASTATE is not set
+# CONFIG_VIDEO_OUTPUT_CONTROL is not set
+# CONFIG_FB is not set
+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+
+#
+# Display device support
+#
+# CONFIG_DISPLAY_SUPPORT is not set
+# CONFIG_SOUND is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_MMC is not set
+# CONFIG_MEMSTICK is not set
+# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
+CONFIG_RTC_LIB=y
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_STAGING_EXCLUDE_BUILD=y
+
+#
+# File systems
+#
+# CONFIG_EXT2_FS is not set
+# CONFIG_EXT3_FS is not set
+# CONFIG_EXT4_FS is not set
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_OCFS2_FS is not set
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_QUOTA is not set
+# CONFIG_AUTOFS_FS is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+# CONFIG_ISO9660_FS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+# CONFIG_MSDOS_FS is not set
+# CONFIG_VFAT_FS is not set
+# CONFIG_NTFS_FS is not set
+
+#
+# Pseudo filesystems
+#
+CONFIG_PROC_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_SYSFS=y
+CONFIG_TMPFS=y
+# CONFIG_TMPFS_POSIX_ACL is not set
+# CONFIG_HUGETLB_PAGE is not set
+# CONFIG_CONFIGFS_FS is not set
+
+#
+# Miscellaneous filesystems
+#
+# CONFIG_ADFS_FS is not set
+# CONFIG_AFFS_FS is not set
+# CONFIG_HFS_FS is not set
+# CONFIG_HFSPLUS_FS is not set
+# CONFIG_BEFS_FS is not set
+# CONFIG_BFS_FS is not set
+# CONFIG_EFS_FS is not set
+# CONFIG_JFFS2_FS is not set
+# CONFIG_CRAMFS is not set
+# CONFIG_VXFS_FS is not set
+# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
+# CONFIG_HPFS_FS is not set
+# CONFIG_QNX4FS_FS is not set
+# CONFIG_ROMFS_FS is not set
+# CONFIG_SYSV_FS is not set
+# CONFIG_UFS_FS is not set
+# CONFIG_NETWORK_FILESYSTEMS is not set
+
+#
+# Partition Types
+#
+# CONFIG_PARTITION_ADVANCED is not set
+CONFIG_MSDOS_PARTITION=y
+CONFIG_NLS=y
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=y
+# CONFIG_NLS_CODEPAGE_737 is not set
+# CONFIG_NLS_CODEPAGE_775 is not set
+# CONFIG_NLS_CODEPAGE_850 is not set
+# CONFIG_NLS_CODEPAGE_852 is not set
+# CONFIG_NLS_CODEPAGE_855 is not set
+# CONFIG_NLS_CODEPAGE_857 is not set
+# CONFIG_NLS_CODEPAGE_860 is not set
+# CONFIG_NLS_CODEPAGE_861 is not set
+# CONFIG_NLS_CODEPAGE_862 is not set
+# CONFIG_NLS_CODEPAGE_863 is not set
+# CONFIG_NLS_CODEPAGE_864 is not set
+# CONFIG_NLS_CODEPAGE_865 is not set
+# CONFIG_NLS_CODEPAGE_866 is not set
+# CONFIG_NLS_CODEPAGE_869 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_ISO8859_8 is not set
+# CONFIG_NLS_CODEPAGE_1250 is not set
+# CONFIG_NLS_CODEPAGE_1251 is not set
+# CONFIG_NLS_ASCII is not set
+CONFIG_NLS_ISO8859_1=y
+# CONFIG_NLS_ISO8859_2 is not set
+# CONFIG_NLS_ISO8859_3 is not set
+# CONFIG_NLS_ISO8859_4 is not set
+# CONFIG_NLS_ISO8859_5 is not set
+# CONFIG_NLS_ISO8859_6 is not set
+# CONFIG_NLS_ISO8859_7 is not set
+# CONFIG_NLS_ISO8859_9 is not set
+# CONFIG_NLS_ISO8859_13 is not set
+# CONFIG_NLS_ISO8859_14 is not set
+# CONFIG_NLS_ISO8859_15 is not set
+# CONFIG_NLS_KOI8_R is not set
+# CONFIG_NLS_KOI8_U is not set
+# CONFIG_NLS_UTF8 is not set
+# CONFIG_DLM is not set
+
+#
+# Kernel hacking
+#
+CONFIG_TRACE_IRQFLAGS_SUPPORT=y
+# CONFIG_PRINTK_TIME is not set
+CONFIG_ENABLE_WARN_DEPRECATED=y
+CONFIG_ENABLE_MUST_CHECK=y
+CONFIG_FRAME_WARN=2048
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_UNUSED_SYMBOLS is not set
+CONFIG_DEBUG_FS=y
+# CONFIG_HEADERS_CHECK is not set
+CONFIG_DEBUG_KERNEL=y
+# CONFIG_DEBUG_SHIRQ is not set
+CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
+CONFIG_SCHED_DEBUG=y
+# CONFIG_SCHEDSTATS is not set
+# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
+# CONFIG_DEBUG_SLAB is not set
+CONFIG_DEBUG_PREEMPT=y
+# CONFIG_DEBUG_RT_MUTEXES is not set
+# CONFIG_RT_MUTEX_TESTER is not set
+CONFIG_DEBUG_SPINLOCK=y
+# CONFIG_DEBUG_MUTEXES is not set
+# CONFIG_DEBUG_LOCK_ALLOC is not set
+# CONFIG_PROVE_LOCKING is not set
+# CONFIG_LOCK_STAT is not set
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
+# CONFIG_DEBUG_KOBJECT is not set
+CONFIG_DEBUG_INFO=y
+# CONFIG_DEBUG_VM is not set
+# CONFIG_DEBUG_WRITECOUNT is not set
+# CONFIG_DEBUG_MEMORY_INIT is not set
+# CONFIG_DEBUG_LIST is not set
+# CONFIG_DEBUG_SG is not set
+# CONFIG_BOOT_PRINTK_DELAY is not set
+# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
+# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
+# CONFIG_FAULT_INJECTION is not set
+CONFIG_SYSCTL_SYSCALL_CHECK=y
+
+#
+# Tracers
+#
+# CONFIG_IRQSOFF_TRACER is not set
+# CONFIG_PREEMPT_TRACER is not set
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
+# CONFIG_SAMPLES is not set
+CONFIG_HAVE_ARCH_KGDB=y
+# CONFIG_KGDB is not set
+CONFIG_CMDLINE=""
+# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_RUNTIME_DEBUG is not set
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+CONFIG_SECURITY=y
+# CONFIG_SECURITYFS is not set
+CONFIG_SECURITY_NETWORK=y
+# CONFIG_SECURITY_NETWORK_XFRM is not set
+# CONFIG_SECURITY_FILE_CAPABILITIES is not set
+CONFIG_SECURITY_DEFAULT_MMAP_MIN_ADDR=0
+CONFIG_CRYPTO=y
+
+#
+# Crypto core or helper
+#
+# CONFIG_CRYPTO_FIPS is not set
+CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_RNG=y
+CONFIG_CRYPTO_MANAGER=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+# CONFIG_CRYPTO_CRYPTD is not set
+# CONFIG_CRYPTO_AUTHENC is not set
+# CONFIG_CRYPTO_TEST is not set
+
+#
+# Authenticated Encryption with Associated Data
+#
+# CONFIG_CRYPTO_CCM is not set
+# CONFIG_CRYPTO_GCM is not set
+# CONFIG_CRYPTO_SEQIV is not set
+
+#
+# Block modes
+#
+CONFIG_CRYPTO_CBC=y
+# CONFIG_CRYPTO_CTR is not set
+# CONFIG_CRYPTO_CTS is not set
+# CONFIG_CRYPTO_ECB is not set
+# CONFIG_CRYPTO_LRW is not set
+# CONFIG_CRYPTO_PCBC is not set
+# CONFIG_CRYPTO_XTS is not set
+
+#
+# Hash modes
+#
+CONFIG_CRYPTO_HMAC=y
+# CONFIG_CRYPTO_XCBC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_MD4 is not set
+CONFIG_CRYPTO_MD5=y
+# CONFIG_CRYPTO_MICHAEL_MIC is not set
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
+# CONFIG_CRYPTO_SHA1 is not set
+# CONFIG_CRYPTO_SHA256 is not set
+# CONFIG_CRYPTO_SHA512 is not set
+# CONFIG_CRYPTO_TGR192 is not set
+# CONFIG_CRYPTO_WP512 is not set
+
+#
+# Ciphers
+#
+# CONFIG_CRYPTO_AES is not set
+# CONFIG_CRYPTO_ANUBIS is not set
+# CONFIG_CRYPTO_ARC4 is not set
+# CONFIG_CRYPTO_BLOWFISH is not set
+# CONFIG_CRYPTO_CAMELLIA is not set
+# CONFIG_CRYPTO_CAST5 is not set
+# CONFIG_CRYPTO_CAST6 is not set
+CONFIG_CRYPTO_DES=y
+# CONFIG_CRYPTO_FCRYPT is not set
+# CONFIG_CRYPTO_KHAZAD is not set
+# CONFIG_CRYPTO_SALSA20 is not set
+# CONFIG_CRYPTO_SEED is not set
+# CONFIG_CRYPTO_SERPENT is not set
+# CONFIG_CRYPTO_TEA is not set
+# CONFIG_CRYPTO_TWOFISH is not set
+
+#
+# Compression
+#
+# CONFIG_CRYPTO_DEFLATE is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
+CONFIG_CRYPTO_HW=y
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
+# CONFIG_CRC_ITU_T is not set
+CONFIG_CRC32=y
+# CONFIG_CRC7 is not set
+# CONFIG_LIBCRC32C is not set
+CONFIG_PLIST=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
diff --git a/arch/mips/include/asm/cpu-features.h b/arch/mips/include/asm/cpu-features.h
index 12d12df..a0d14f8 100644
--- a/arch/mips/include/asm/cpu-features.h
+++ b/arch/mips/include/asm/cpu-features.h
@@ -38,6 +38,9 @@
#ifndef cpu_has_tx39_cache
#define cpu_has_tx39_cache (cpu_data[0].options & MIPS_CPU_TX39_CACHE)
#endif
+#ifndef cpu_has_octeon_cache
+#define cpu_has_octeon_cache 0
+#endif
#ifndef cpu_has_fpu
#define cpu_has_fpu (current_cpu_data.options & MIPS_CPU_FPU)
#define raw_cpu_has_fpu (raw_current_cpu_data.options & MIPS_CPU_FPU)
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index 229a786..c018727 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -33,6 +33,7 @@
#define PRID_COMP_TOSHIBA 0x070000
#define PRID_COMP_LSI 0x080000
#define PRID_COMP_LEXRA 0x0b0000
+#define PRID_COMP_CAVIUM 0x0d0000
/*
@@ -114,6 +115,18 @@
#define PRID_IMP_BCM3302 0x9000
/*
+ * These are the PRID's for when 23:16 == PRID_COMP_CAVIUM
+ */
+
+#define PRID_IMP_CAVIUM_CN38XX 0x0000
+#define PRID_IMP_CAVIUM_CN31XX 0x0100
+#define PRID_IMP_CAVIUM_CN30XX 0x0200
+#define PRID_IMP_CAVIUM_CN58XX 0x0300
+#define PRID_IMP_CAVIUM_CN56XX 0x0400
+#define PRID_IMP_CAVIUM_CN50XX 0x0600
+#define PRID_IMP_CAVIUM_CN52XX 0x0700
+
+/*
* Definitions for 7:0 on legacy processors
*/
@@ -203,6 +216,7 @@ enum cpu_type_enum {
* MIPS64 class processors
*/
CPU_5KC, CPU_20KC, CPU_25KF, CPU_SB1, CPU_SB1A, CPU_LOONGSON2,
+ CPU_CAVIUM_OCTEON,
CPU_LAST
};
diff --git a/arch/mips/include/asm/hazards.h b/arch/mips/include/asm/hazards.h
index 2de638f..43baed1 100644
--- a/arch/mips/include/asm/hazards.h
+++ b/arch/mips/include/asm/hazards.h
@@ -42,7 +42,7 @@ ASMMACRO(_ehb,
/*
* TLB hazards
*/
-#if defined(CONFIG_CPU_MIPSR2)
+#if defined(CONFIG_CPU_MIPSR2) && !defined(CONFIG_CPU_CAVIUM_OCTEON)
/*
* MIPSR2 defines ehb for hazard avoidance
@@ -138,7 +138,7 @@ do { \
__instruction_hazard(); \
} while (0)
-#elif defined(CONFIG_CPU_R10000)
+#elif defined(CONFIG_CPU_R10000) || defined(CONFIG_CPU_CAVIUM_OCTEON)
/*
* R10000 rocks - all hazards handled in hardware, so this becomes a nobrainer.
diff --git a/arch/mips/include/asm/io.h b/arch/mips/include/asm/io.h
index 501a40b..436878e 100644
--- a/arch/mips/include/asm/io.h
+++ b/arch/mips/include/asm/io.h
@@ -295,6 +295,12 @@ static inline void iounmap(const volatile void __iomem *addr)
#undef __IS_KSEG1
}
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+#define war_octeon_io_reorder_wmb() wmb()
+#else
+#define war_octeon_io_reorder_wmb() do { } while (0)
+#endif
+
#define __BUILD_MEMORY_SINGLE(pfx, bwlq, type, irq) \
\
static inline void pfx##write##bwlq(type val, \
@@ -303,6 +309,8 @@ static inline void pfx##write##bwlq(type val, \
volatile type *__mem; \
type __val; \
\
+ war_octeon_io_reorder_wmb(); \
+ \
__mem = (void *)__swizzle_addr_##bwlq((unsigned long)(mem)); \
\
__val = pfx##ioswab##bwlq(__mem, val); \
@@ -370,6 +378,8 @@ static inline void pfx##out##bwlq##p(type val, unsigned long port) \
volatile type *__addr; \
type __val; \
\
+ war_octeon_io_reorder_wmb(); \
+ \
__addr = (void *)__swizzle_addr_##bwlq(mips_io_port_base + port); \
\
__val = pfx##ioswab##bwlq(__addr, val); \
@@ -504,8 +514,12 @@ BUILDSTRING(q, u64)
#endif
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+#define mmiowb() wmb()
+#else
/* Depends on MIPS II instruction set */
#define mmiowb() asm volatile ("sync" ::: "memory")
+#endif
static inline void memset_io(volatile void __iomem *addr, unsigned char val, int count)
{
diff --git a/arch/mips/include/asm/irq.h b/arch/mips/include/asm/irq.h
index abc62aa..3214ade 100644
--- a/arch/mips/include/asm/irq.h
+++ b/arch/mips/include/asm/irq.h
@@ -66,7 +66,7 @@ extern void smtc_forward_irq(unsigned int irq);
*/
#define IRQ_AFFINITY_HOOK(irq) \
do { \
- if (!cpu_isset(smp_processor_id(), irq_desc[irq].affinity)) { \
+ if (!cpumask_test_cpu(smp_processor_id(), irq_desc[irq].affinity)) {\
smtc_forward_irq(irq); \
irq_exit(); \
return; \
diff --git a/arch/mips/include/asm/mach-au1x00/au1000.h b/arch/mips/include/asm/mach-au1x00/au1000.h
index 0d302ba..62f91f5 100644
--- a/arch/mips/include/asm/mach-au1x00/au1000.h
+++ b/arch/mips/include/asm/mach-au1x00/au1000.h
@@ -91,14 +91,57 @@ static inline u32 au_readl(unsigned long reg)
return *(volatile u32 *)reg;
}
+/* Early Au1000 have a write-only SYS_CPUPLL register. */
+static inline int au1xxx_cpu_has_pll_wo(void)
+{
+ switch (read_c0_prid()) {
+ case 0x00030100: /* Au1000 DA */
+ case 0x00030201: /* Au1000 HA */
+ case 0x00030202: /* Au1000 HB */
+ return 1;
+ }
+ return 0;
+}
+
+/* does CPU need CONFIG[OD] set to fix tons of errata? */
+static inline int au1xxx_cpu_needs_config_od(void)
+{
+ /*
+ * c0_config.od (bit 19) was write only (and read as 0) on the
+ * early revisions of Alchemy SOCs. It disables the bus trans-
+ * action overlapping and needs to be set to fix various errata.
+ */
+ switch (read_c0_prid()) {
+ case 0x00030100: /* Au1000 DA */
+ case 0x00030201: /* Au1000 HA */
+ case 0x00030202: /* Au1000 HB */
+ case 0x01030200: /* Au1500 AB */
+ /*
+ * Au1100/Au1200 errata actually keep silence about this bit,
+ * so we set it just in case for those revisions that require
+ * it to be set according to the (now gone) cpu_table.
+ */
+ case 0x02030200: /* Au1100 AB */
+ case 0x02030201: /* Au1100 BA */
+ case 0x02030202: /* Au1100 BC */
+ case 0x04030201: /* Au1200 AC */
+ return 1;
+ }
+ return 0;
+}
/* arch/mips/au1000/common/clocks.c */
extern void set_au1x00_speed(unsigned int new_freq);
extern unsigned int get_au1x00_speed(void);
extern void set_au1x00_uart_baud_base(unsigned long new_baud_base);
extern unsigned long get_au1x00_uart_baud_base(void);
-extern void set_au1x00_lcd_clock(void);
-extern unsigned int get_au1x00_lcd_clock(void);
+extern unsigned long au1xxx_calc_clock(void);
+
+/* PM: arch/mips/alchemy/common/sleeper.S, power.c, irq.c */
+void au1xxx_save_and_sleep(void);
+void au_sleep(void);
+void save_au1xxx_intctl(void);
+void restore_au1xxx_intctl(void);
/*
* Every board describes its IRQ mapping with this table.
@@ -109,10 +152,11 @@ struct au1xxx_irqmap {
int im_request;
};
-/*
- * init_IRQ looks for a table with this name.
- */
-extern struct au1xxx_irqmap au1xxx_irq_map[];
+/* core calls this function to let boards initialize other IRQ sources */
+void board_init_irq(void);
+
+/* boards call this to register additional (GPIO) interrupts */
+void au1xxx_setup_irqmap(struct au1xxx_irqmap *map, int count);
#endif /* !defined (_LANGUAGE_ASSEMBLY) */
@@ -505,15 +549,6 @@ extern struct au1xxx_irqmap au1xxx_irq_map[];
#define IC1_TESTBIT 0xB1800080
-/* Interrupt Configuration Modes */
-#define INTC_INT_DISABLED 0x0
-#define INTC_INT_RISE_EDGE 0x1
-#define INTC_INT_FALL_EDGE 0x2
-#define INTC_INT_RISE_AND_FALL_EDGE 0x3
-#define INTC_INT_HIGH_LEVEL 0x5
-#define INTC_INT_LOW_LEVEL 0x6
-#define INTC_INT_HIGH_AND_LOW_LEVEL 0x7
-
/* Interrupt Numbers */
/* Au1000 */
#ifdef CONFIG_SOC_AU1000
@@ -1525,6 +1560,10 @@ enum soc_au1200_ints {
#define SYS_SLPPWR 0xB1900078
#define SYS_SLEEP 0xB190007C
+#define SYS_WAKEMSK_D2 (1 << 9)
+#define SYS_WAKEMSK_M2 (1 << 8)
+#define SYS_WAKEMSK_GPIO(x) (1 << (x))
+
/* Clock Controller */
#define SYS_FREQCTRL0 0xB1900020
# define SYS_FC_FRDIV2_BIT 22
@@ -1749,24 +1788,4 @@ static AU1X00_SYS * const sys = (AU1X00_SYS *)SYS_BASE;
#endif
-/*
- * Processor information based on PRID.
- * Copied from PowerPC.
- */
-#ifndef _LANGUAGE_ASSEMBLY
-struct cpu_spec {
- /* CPU is matched via (PRID & prid_mask) == prid_value */
- unsigned int prid_mask;
- unsigned int prid_value;
-
- char *cpu_name;
- unsigned char cpu_od; /* Set Config[OD] */
- unsigned char cpu_bclk; /* Enable BCLK switching */
- unsigned char cpu_pll_wo; /* sys_cpupll reg. write-only */
-};
-
-extern struct cpu_spec cpu_specs[];
-extern struct cpu_spec *cur_cpu_spec[];
-#endif
-
#endif
diff --git a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
index 44a67bf..06f68f4 100644
--- a/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
+++ b/arch/mips/include/asm/mach-au1x00/au1xxx_dbdma.h
@@ -357,6 +357,11 @@ u32 au1xxx_dbdma_put_dscr(u32 chanid, au1x_ddma_desc_t *dscr);
u32 au1xxx_ddma_add_device(dbdev_tab_t *dev);
extern void au1xxx_ddma_del_device(u32 devid);
void *au1xxx_ddma_get_nextptr_virt(au1x_ddma_desc_t *dp);
+#ifdef CONFIG_PM
+void au1xxx_dbdma_suspend(void);
+void au1xxx_dbdma_resume(void);
+#endif
+
/*
* Some compatibilty macros -- needed to make changes to API
diff --git a/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
new file mode 100644
index 0000000..04ce6e6
--- /dev/null
+++ b/arch/mips/include/asm/mach-cavium-octeon/cpu-feature-overrides.h
@@ -0,0 +1,78 @@
+/*
+ * 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 Cavium Networks
+ */
+#ifndef __ASM_MACH_CAVIUM_OCTEON_CPU_FEATURE_OVERRIDES_H
+#define __ASM_MACH_CAVIUM_OCTEON_CPU_FEATURE_OVERRIDES_H
+
+#include <linux/types.h>
+#include <asm/mipsregs.h>
+
+/*
+ * Cavium Octeons are MIPS64v2 processors
+ */
+#define cpu_dcache_line_size() 128
+#define cpu_icache_line_size() 128
+
+
+#define cpu_has_4kex 1
+#define cpu_has_3k_cache 0
+#define cpu_has_4k_cache 0
+#define cpu_has_tx39_cache 0
+#define cpu_has_fpu 0
+#define cpu_has_counter 1
+#define cpu_has_watch 1
+#define cpu_has_divec 1
+#define cpu_has_vce 0
+#define cpu_has_cache_cdex_p 0
+#define cpu_has_cache_cdex_s 0
+#define cpu_has_prefetch 1
+
+/*
+ * We should disable LL/SC on non SMP systems as it is faster to
+ * disable interrupts for atomic access than a LL/SC. Unfortunatly we
+ * cannot as this breaks asm/futex.h
+ */
+#define cpu_has_llsc 1
+#define cpu_has_vtag_icache 1
+#define cpu_has_dc_aliases 0
+#define cpu_has_ic_fills_f_dc 0
+#define cpu_has_64bits 1
+#define cpu_has_octeon_cache 1
+#define cpu_has_saa octeon_has_saa()
+#define cpu_has_mips32r1 0
+#define cpu_has_mips32r2 0
+#define cpu_has_mips64r1 0
+#define cpu_has_mips64r2 1
+#define cpu_has_dsp 0
+#define cpu_has_mipsmt 0
+#define cpu_has_userlocal 0
+#define cpu_has_vint 0
+#define cpu_has_veic 0
+#define ARCH_HAS_READ_CURRENT_TIMER 1
+#define ARCH_HAS_IRQ_PER_CPU 1
+#define ARCH_HAS_SPINLOCK_PREFETCH 1
+#define spin_lock_prefetch(x) prefetch(x)
+#define PREFETCH_STRIDE 128
+
+static inline int read_current_timer(unsigned long *result)
+{
+ asm volatile ("rdhwr %0,$31\n"
+#ifndef CONFIG_64BIT
+ "\tsll %0, 0"
+#endif
+ : "=r" (*result));
+ return 0;
+}
+
+static inline int octeon_has_saa(void)
+{
+ int id;
+ asm volatile ("mfc0 %0, $15,0" : "=r" (id));
+ return id >= 0x000d0300;
+}
+
+#endif
diff --git a/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
new file mode 100644
index 0000000..f30fce9
--- /dev/null
+++ b/arch/mips/include/asm/mach-cavium-octeon/dma-coherence.h
@@ -0,0 +1,64 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Ralf Baechle <ralf@linux-mips.org>
+ *
+ *
+ * Similar to mach-generic/dma-coherence.h except
+ * plat_device_is_coherent hard coded to return 1.
+ *
+ */
+#ifndef __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H
+#define __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H
+
+struct device;
+
+dma_addr_t octeon_map_dma_mem(struct device *, void *, size_t);
+void octeon_unmap_dma_mem(struct device *, dma_addr_t);
+
+static inline dma_addr_t plat_map_dma_mem(struct device *dev, void *addr,
+ size_t size)
+{
+ return octeon_map_dma_mem(dev, addr, size);
+}
+
+static inline dma_addr_t plat_map_dma_mem_page(struct device *dev,
+ struct page *page)
+{
+ return octeon_map_dma_mem(dev, page_address(page), PAGE_SIZE);
+}
+
+static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
+{
+ return dma_addr;
+}
+
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
+{
+ octeon_unmap_dma_mem(dev, dma_addr);
+}
+
+static inline int plat_dma_supported(struct device *dev, u64 mask)
+{
+ return 1;
+}
+
+static inline void plat_extra_sync_for_device(struct device *dev)
+{
+ mb();
+}
+
+static inline int plat_device_is_coherent(struct device *dev)
+{
+ return 1;
+}
+
+static inline int plat_dma_mapping_error(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ return dma_addr == -1;
+}
+
+#endif /* __ASM_MACH_CAVIUM_OCTEON_DMA_COHERENCE_H */
diff --git a/arch/mips/include/asm/mach-cavium-octeon/irq.h b/arch/mips/include/asm/mach-cavium-octeon/irq.h
new file mode 100644
index 0000000..d32220f
--- /dev/null
+++ b/arch/mips/include/asm/mach-cavium-octeon/irq.h
@@ -0,0 +1,244 @@
+/*
+ * 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-2008 Cavium Networks
+ */
+#ifndef __OCTEON_IRQ_H__
+#define __OCTEON_IRQ_H__
+
+#define NR_IRQS OCTEON_IRQ_LAST
+#define MIPS_CPU_IRQ_BASE OCTEON_IRQ_SW0
+
+/* 0 - 7 represent the i8259 master */
+#define OCTEON_IRQ_I8259M0 0
+#define OCTEON_IRQ_I8259M1 1
+#define OCTEON_IRQ_I8259M2 2
+#define OCTEON_IRQ_I8259M3 3
+#define OCTEON_IRQ_I8259M4 4
+#define OCTEON_IRQ_I8259M5 5
+#define OCTEON_IRQ_I8259M6 6
+#define OCTEON_IRQ_I8259M7 7
+/* 8 - 15 represent the i8259 slave */
+#define OCTEON_IRQ_I8259S0 8
+#define OCTEON_IRQ_I8259S1 9
+#define OCTEON_IRQ_I8259S2 10
+#define OCTEON_IRQ_I8259S3 11
+#define OCTEON_IRQ_I8259S4 12
+#define OCTEON_IRQ_I8259S5 13
+#define OCTEON_IRQ_I8259S6 14
+#define OCTEON_IRQ_I8259S7 15
+/* 16 - 23 represent the 8 MIPS standard interrupt sources */
+#define OCTEON_IRQ_SW0 16
+#define OCTEON_IRQ_SW1 17
+#define OCTEON_IRQ_CIU0 18
+#define OCTEON_IRQ_CIU1 19
+#define OCTEON_IRQ_CIU4 20
+#define OCTEON_IRQ_5 21
+#define OCTEON_IRQ_PERF 22
+#define OCTEON_IRQ_TIMER 23
+/* 24 - 87 represent the sources in CIU_INTX_EN0 */
+#define OCTEON_IRQ_WORKQ0 24
+#define OCTEON_IRQ_WORKQ1 25
+#define OCTEON_IRQ_WORKQ2 26
+#define OCTEON_IRQ_WORKQ3 27
+#define OCTEON_IRQ_WORKQ4 28
+#define OCTEON_IRQ_WORKQ5 29
+#define OCTEON_IRQ_WORKQ6 30
+#define OCTEON_IRQ_WORKQ7 31
+#define OCTEON_IRQ_WORKQ8 32
+#define OCTEON_IRQ_WORKQ9 33
+#define OCTEON_IRQ_WORKQ10 34
+#define OCTEON_IRQ_WORKQ11 35
+#define OCTEON_IRQ_WORKQ12 36
+#define OCTEON_IRQ_WORKQ13 37
+#define OCTEON_IRQ_WORKQ14 38
+#define OCTEON_IRQ_WORKQ15 39
+#define OCTEON_IRQ_GPIO0 40
+#define OCTEON_IRQ_GPIO1 41
+#define OCTEON_IRQ_GPIO2 42
+#define OCTEON_IRQ_GPIO3 43
+#define OCTEON_IRQ_GPIO4 44
+#define OCTEON_IRQ_GPIO5 45
+#define OCTEON_IRQ_GPIO6 46
+#define OCTEON_IRQ_GPIO7 47
+#define OCTEON_IRQ_GPIO8 48
+#define OCTEON_IRQ_GPIO9 49
+#define OCTEON_IRQ_GPIO10 50
+#define OCTEON_IRQ_GPIO11 51
+#define OCTEON_IRQ_GPIO12 52
+#define OCTEON_IRQ_GPIO13 53
+#define OCTEON_IRQ_GPIO14 54
+#define OCTEON_IRQ_GPIO15 55
+#define OCTEON_IRQ_MBOX0 56
+#define OCTEON_IRQ_MBOX1 57
+#define OCTEON_IRQ_UART0 58
+#define OCTEON_IRQ_UART1 59
+#define OCTEON_IRQ_PCI_INT0 60
+#define OCTEON_IRQ_PCI_INT1 61
+#define OCTEON_IRQ_PCI_INT2 62
+#define OCTEON_IRQ_PCI_INT3 63
+#define OCTEON_IRQ_PCI_MSI0 64
+#define OCTEON_IRQ_PCI_MSI1 65
+#define OCTEON_IRQ_PCI_MSI2 66
+#define OCTEON_IRQ_PCI_MSI3 67
+#define OCTEON_IRQ_RESERVED68 68 /* Summary of CIU_INT_SUM1 */
+#define OCTEON_IRQ_TWSI 69
+#define OCTEON_IRQ_RML 70
+#define OCTEON_IRQ_TRACE 71
+#define OCTEON_IRQ_GMX_DRP0 72
+#define OCTEON_IRQ_GMX_DRP1 73
+#define OCTEON_IRQ_IPD_DRP 74
+#define OCTEON_IRQ_KEY_ZERO 75
+#define OCTEON_IRQ_TIMER0 76
+#define OCTEON_IRQ_TIMER1 77
+#define OCTEON_IRQ_TIMER2 78
+#define OCTEON_IRQ_TIMER3 79
+#define OCTEON_IRQ_USB0 80
+#define OCTEON_IRQ_PCM 81
+#define OCTEON_IRQ_MPI 82
+#define OCTEON_IRQ_TWSI2 83
+#define OCTEON_IRQ_POWIQ 84
+#define OCTEON_IRQ_IPDPPTHR 85
+#define OCTEON_IRQ_MII0 86
+#define OCTEON_IRQ_BOOTDMA 87
+/* 88 - 151 represent the sources in CIU_INTX_EN1 */
+#define OCTEON_IRQ_WDOG0 88
+#define OCTEON_IRQ_WDOG1 89
+#define OCTEON_IRQ_WDOG2 90
+#define OCTEON_IRQ_WDOG3 91
+#define OCTEON_IRQ_WDOG4 92
+#define OCTEON_IRQ_WDOG5 93
+#define OCTEON_IRQ_WDOG6 94
+#define OCTEON_IRQ_WDOG7 95
+#define OCTEON_IRQ_WDOG8 96
+#define OCTEON_IRQ_WDOG9 97
+#define OCTEON_IRQ_WDOG10 98
+#define OCTEON_IRQ_WDOG11 99
+#define OCTEON_IRQ_WDOG12 100
+#define OCTEON_IRQ_WDOG13 101
+#define OCTEON_IRQ_WDOG14 102
+#define OCTEON_IRQ_WDOG15 103
+#define OCTEON_IRQ_UART2 104
+#define OCTEON_IRQ_USB1 105
+#define OCTEON_IRQ_MII1 106
+#define OCTEON_IRQ_RESERVED107 107
+#define OCTEON_IRQ_RESERVED108 108
+#define OCTEON_IRQ_RESERVED109 109
+#define OCTEON_IRQ_RESERVED110 110
+#define OCTEON_IRQ_RESERVED111 111
+#define OCTEON_IRQ_RESERVED112 112
+#define OCTEON_IRQ_RESERVED113 113
+#define OCTEON_IRQ_RESERVED114 114
+#define OCTEON_IRQ_RESERVED115 115
+#define OCTEON_IRQ_RESERVED116 116
+#define OCTEON_IRQ_RESERVED117 117
+#define OCTEON_IRQ_RESERVED118 118
+#define OCTEON_IRQ_RESERVED119 119
+#define OCTEON_IRQ_RESERVED120 120
+#define OCTEON_IRQ_RESERVED121 121
+#define OCTEON_IRQ_RESERVED122 122
+#define OCTEON_IRQ_RESERVED123 123
+#define OCTEON_IRQ_RESERVED124 124
+#define OCTEON_IRQ_RESERVED125 125
+#define OCTEON_IRQ_RESERVED126 126
+#define OCTEON_IRQ_RESERVED127 127
+#define OCTEON_IRQ_RESERVED128 128
+#define OCTEON_IRQ_RESERVED129 129
+#define OCTEON_IRQ_RESERVED130 130
+#define OCTEON_IRQ_RESERVED131 131
+#define OCTEON_IRQ_RESERVED132 132
+#define OCTEON_IRQ_RESERVED133 133
+#define OCTEON_IRQ_RESERVED134 134
+#define OCTEON_IRQ_RESERVED135 135
+#define OCTEON_IRQ_RESERVED136 136
+#define OCTEON_IRQ_RESERVED137 137
+#define OCTEON_IRQ_RESERVED138 138
+#define OCTEON_IRQ_RESERVED139 139
+#define OCTEON_IRQ_RESERVED140 140
+#define OCTEON_IRQ_RESERVED141 141
+#define OCTEON_IRQ_RESERVED142 142
+#define OCTEON_IRQ_RESERVED143 143
+#define OCTEON_IRQ_RESERVED144 144
+#define OCTEON_IRQ_RESERVED145 145
+#define OCTEON_IRQ_RESERVED146 146
+#define OCTEON_IRQ_RESERVED147 147
+#define OCTEON_IRQ_RESERVED148 148
+#define OCTEON_IRQ_RESERVED149 149
+#define OCTEON_IRQ_RESERVED150 150
+#define OCTEON_IRQ_RESERVED151 151
+
+#ifdef CONFIG_PCI_MSI
+/* 152 - 215 represent the MSI interrupts 0-63 */
+#define OCTEON_IRQ_MSI_BIT0 152
+#define OCTEON_IRQ_MSI_BIT1 153
+#define OCTEON_IRQ_MSI_BIT2 154
+#define OCTEON_IRQ_MSI_BIT3 155
+#define OCTEON_IRQ_MSI_BIT4 156
+#define OCTEON_IRQ_MSI_BIT5 157
+#define OCTEON_IRQ_MSI_BIT6 158
+#define OCTEON_IRQ_MSI_BIT7 159
+#define OCTEON_IRQ_MSI_BIT8 160
+#define OCTEON_IRQ_MSI_BIT9 161
+#define OCTEON_IRQ_MSI_BIT10 162
+#define OCTEON_IRQ_MSI_BIT11 163
+#define OCTEON_IRQ_MSI_BIT12 164
+#define OCTEON_IRQ_MSI_BIT13 165
+#define OCTEON_IRQ_MSI_BIT14 166
+#define OCTEON_IRQ_MSI_BIT15 167
+#define OCTEON_IRQ_MSI_BIT16 168
+#define OCTEON_IRQ_MSI_BIT17 169
+#define OCTEON_IRQ_MSI_BIT18 170
+#define OCTEON_IRQ_MSI_BIT19 171
+#define OCTEON_IRQ_MSI_BIT20 172
+#define OCTEON_IRQ_MSI_BIT21 173
+#define OCTEON_IRQ_MSI_BIT22 174
+#define OCTEON_IRQ_MSI_BIT23 175
+#define OCTEON_IRQ_MSI_BIT24 176
+#define OCTEON_IRQ_MSI_BIT25 177
+#define OCTEON_IRQ_MSI_BIT26 178
+#define OCTEON_IRQ_MSI_BIT27 179
+#define OCTEON_IRQ_MSI_BIT28 180
+#define OCTEON_IRQ_MSI_BIT29 181
+#define OCTEON_IRQ_MSI_BIT30 182
+#define OCTEON_IRQ_MSI_BIT31 183
+#define OCTEON_IRQ_MSI_BIT32 184
+#define OCTEON_IRQ_MSI_BIT33 185
+#define OCTEON_IRQ_MSI_BIT34 186
+#define OCTEON_IRQ_MSI_BIT35 187
+#define OCTEON_IRQ_MSI_BIT36 188
+#define OCTEON_IRQ_MSI_BIT37 189
+#define OCTEON_IRQ_MSI_BIT38 190
+#define OCTEON_IRQ_MSI_BIT39 191
+#define OCTEON_IRQ_MSI_BIT40 192
+#define OCTEON_IRQ_MSI_BIT41 193
+#define OCTEON_IRQ_MSI_BIT42 194
+#define OCTEON_IRQ_MSI_BIT43 195
+#define OCTEON_IRQ_MSI_BIT44 196
+#define OCTEON_IRQ_MSI_BIT45 197
+#define OCTEON_IRQ_MSI_BIT46 198
+#define OCTEON_IRQ_MSI_BIT47 199
+#define OCTEON_IRQ_MSI_BIT48 200
+#define OCTEON_IRQ_MSI_BIT49 201
+#define OCTEON_IRQ_MSI_BIT50 202
+#define OCTEON_IRQ_MSI_BIT51 203
+#define OCTEON_IRQ_MSI_BIT52 204
+#define OCTEON_IRQ_MSI_BIT53 205
+#define OCTEON_IRQ_MSI_BIT54 206
+#define OCTEON_IRQ_MSI_BIT55 207
+#define OCTEON_IRQ_MSI_BIT56 208
+#define OCTEON_IRQ_MSI_BIT57 209
+#define OCTEON_IRQ_MSI_BIT58 210
+#define OCTEON_IRQ_MSI_BIT59 211
+#define OCTEON_IRQ_MSI_BIT60 212
+#define OCTEON_IRQ_MSI_BIT61 213
+#define OCTEON_IRQ_MSI_BIT62 214
+#define OCTEON_IRQ_MSI_BIT63 215
+
+#define OCTEON_IRQ_LAST 216
+#else
+#define OCTEON_IRQ_LAST 152
+#endif
+
+#endif
diff --git a/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
new file mode 100644
index 0000000..0b2b5eb
--- /dev/null
+++ b/arch/mips/include/asm/mach-cavium-octeon/kernel-entry-init.h
@@ -0,0 +1,131 @@
+/*
+ * 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-2008 Cavium Networks, Inc
+ */
+#ifndef __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H
+#define __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H
+
+
+#define CP0_CYCLE_COUNTER $9, 6
+#define CP0_CVMCTL_REG $9, 7
+#define CP0_CVMMEMCTL_REG $11,7
+#define CP0_PRID_REG $15, 0
+#define CP0_PRID_OCTEON_PASS1 0x000d0000
+#define CP0_PRID_OCTEON_CN30XX 0x000d0200
+
+.macro kernel_entry_setup
+ # Registers set by bootloader:
+ # (only 32 bits set by bootloader, all addresses are physical
+ # addresses, and need to have the appropriate memory region set
+ # by the kernel
+ # a0 = argc
+ # a1 = argv (kseg0 compat addr)
+ # a2 = 1 if init core, zero otherwise
+ # a3 = address of boot descriptor block
+ .set push
+ .set arch=octeon
+ # Read the cavium mem control register
+ dmfc0 v0, CP0_CVMMEMCTL_REG
+ # Clear the lower 6 bits, the CVMSEG size
+ dins v0, $0, 0, 6
+ ori v0, CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE
+ dmtc0 v0, CP0_CVMMEMCTL_REG # Write the cavium mem control register
+ dmfc0 v0, CP0_CVMCTL_REG # Read the cavium control register
+#ifdef CONFIG_CAVIUM_OCTEON_HW_FIX_UNALIGNED
+ # Disable unaligned load/store support but leave HW fixup enabled
+ or v0, v0, 0x5001
+ xor v0, v0, 0x1001
+#else
+ # Disable unaligned load/store and HW fixup support
+ or v0, v0, 0x5001
+ xor v0, v0, 0x5001
+#endif
+ # Read the processor ID register
+ mfc0 v1, CP0_PRID_REG
+ # Disable instruction prefetching (Octeon Pass1 errata)
+ or v0, v0, 0x2000
+ # Skip reenable of prefetching for Octeon Pass1
+ beq v1, CP0_PRID_OCTEON_PASS1, skip
+ nop
+ # Reenable instruction prefetching, not on Pass1
+ xor v0, v0, 0x2000
+ # Strip off pass number off of processor id
+ srl v1, 8
+ sll v1, 8
+ # CN30XX needs some extra stuff turned off for better performance
+ bne v1, CP0_PRID_OCTEON_CN30XX, skip
+ nop
+ # CN30XX Use random Icache replacement
+ or v0, v0, 0x400
+ # CN30XX Disable instruction prefetching
+ or v0, v0, 0x2000
+skip:
+ # Write the cavium control register
+ dmtc0 v0, CP0_CVMCTL_REG
+ sync
+ # Flush dcache after config change
+ cache 9, 0($0)
+ # Get my core id
+ rdhwr v0, $0
+ # Jump the master to kernel_entry
+ bne a2, zero, octeon_main_processor
+ nop
+
+#ifdef CONFIG_SMP
+
+ #
+ # All cores other than the master need to wait here for SMP bootstrap
+ # to begin
+ #
+
+ # This is the variable where the next core to boot os stored
+ PTR_LA t0, octeon_processor_boot
+octeon_spin_wait_boot:
+ # Get the core id of the next to be booted
+ LONG_L t1, (t0)
+ # Keep looping if it isn't me
+ bne t1, v0, octeon_spin_wait_boot
+ nop
+ # Get my GP from the global variable
+ PTR_LA t0, octeon_processor_gp
+ LONG_L gp, (t0)
+ # Get my SP from the global variable
+ PTR_LA t0, octeon_processor_sp
+ LONG_L sp, (t0)
+ # Set the SP global variable to zero so the master knows we've started
+ LONG_S zero, (t0)
+#ifdef __OCTEON__
+ syncw
+ syncw
+#else
+ sync
+#endif
+ # Jump to the normal Linux SMP entry point
+ j smp_bootstrap
+ nop
+#else /* CONFIG_SMP */
+
+ #
+ # Someone tried to boot SMP with a non SMP kernel. All extra cores
+ # will halt here.
+ #
+octeon_wait_forever:
+ wait
+ b octeon_wait_forever
+ nop
+
+#endif /* CONFIG_SMP */
+octeon_main_processor:
+ .set pop
+.endm
+
+/*
+ * Do SMP slave processor setup necessary before we can savely execute C code.
+ */
+ .macro smp_slave_setup
+ .endm
+
+#endif /* __ASM_MACH_CAVIUM_OCTEON_KERNEL_ENTRY_H */
diff --git a/arch/mips/include/asm/mach-cavium-octeon/war.h b/arch/mips/include/asm/mach-cavium-octeon/war.h
new file mode 100644
index 0000000..c4712d7
--- /dev/null
+++ b/arch/mips/include/asm/mach-cavium-octeon/war.h
@@ -0,0 +1,26 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ * Copyright (C) 2008 Cavium Networks <support@caviumnetworks.com>
+ */
+#ifndef __ASM_MIPS_MACH_CAVIUM_OCTEON_WAR_H
+#define __ASM_MIPS_MACH_CAVIUM_OCTEON_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MIPS_MACH_CAVIUM_OCTEON_WAR_H */
diff --git a/arch/mips/include/asm/mach-generic/dma-coherence.h b/arch/mips/include/asm/mach-generic/dma-coherence.h
index 76e04e7..36c611b 100644
--- a/arch/mips/include/asm/mach-generic/dma-coherence.h
+++ b/arch/mips/include/asm/mach-generic/dma-coherence.h
@@ -28,10 +28,34 @@ static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
return dma_addr;
}
-static inline void plat_unmap_dma_mem(dma_addr_t dma_addr)
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
{
}
+static inline int plat_dma_supported(struct device *dev, u64 mask)
+{
+ /*
+ * we fall back to GFP_DMA when the mask isn't all 1s,
+ * so we can't guarantee allocations that must be
+ * within a tighter range than GFP_DMA..
+ */
+ if (mask < DMA_BIT_MASK(24))
+ return 0;
+
+ return 1;
+}
+
+static inline void plat_extra_sync_for_device(struct device *dev)
+{
+ return;
+}
+
+static inline int plat_dma_mapping_error(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ return 0;
+}
+
static inline int plat_device_is_coherent(struct device *dev)
{
#ifdef CONFIG_DMA_COHERENT
diff --git a/arch/mips/include/asm/mach-ip27/dma-coherence.h b/arch/mips/include/asm/mach-ip27/dma-coherence.h
index ed7e622..4c21bfc 100644
--- a/arch/mips/include/asm/mach-ip27/dma-coherence.h
+++ b/arch/mips/include/asm/mach-ip27/dma-coherence.h
@@ -38,10 +38,34 @@ static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
return dma_addr & ~(0xffUL << 56);
}
-static inline void plat_unmap_dma_mem(dma_addr_t dma_addr)
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
{
}
+static inline int plat_dma_supported(struct device *dev, u64 mask)
+{
+ /*
+ * we fall back to GFP_DMA when the mask isn't all 1s,
+ * so we can't guarantee allocations that must be
+ * within a tighter range than GFP_DMA..
+ */
+ if (mask < DMA_BIT_MASK(24))
+ return 0;
+
+ return 1;
+}
+
+static inline void plat_extra_sync_for_device(struct device *dev)
+{
+ return;
+}
+
+static inline int plat_dma_mapping_error(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ return 0;
+}
+
static inline int plat_device_is_coherent(struct device *dev)
{
return 1; /* IP27 non-cohernet mode is unsupported */
diff --git a/arch/mips/include/asm/mach-ip32/dma-coherence.h b/arch/mips/include/asm/mach-ip32/dma-coherence.h
index a5511eb..7ae40f4 100644
--- a/arch/mips/include/asm/mach-ip32/dma-coherence.h
+++ b/arch/mips/include/asm/mach-ip32/dma-coherence.h
@@ -60,10 +60,34 @@ static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
return addr;
}
-static inline void plat_unmap_dma_mem(dma_addr_t dma_addr)
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
{
}
+static inline int plat_dma_supported(struct device *dev, u64 mask)
+{
+ /*
+ * we fall back to GFP_DMA when the mask isn't all 1s,
+ * so we can't guarantee allocations that must be
+ * within a tighter range than GFP_DMA..
+ */
+ if (mask < DMA_BIT_MASK(24))
+ return 0;
+
+ return 1;
+}
+
+static inline void plat_extra_sync_for_device(struct device *dev)
+{
+ return;
+}
+
+static inline int plat_dma_mapping_error(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ return 0;
+}
+
static inline int plat_device_is_coherent(struct device *dev)
{
return 0; /* IP32 is non-cohernet */
diff --git a/arch/mips/include/asm/mach-jazz/dma-coherence.h b/arch/mips/include/asm/mach-jazz/dma-coherence.h
index d66979a..1c7cd27 100644
--- a/arch/mips/include/asm/mach-jazz/dma-coherence.h
+++ b/arch/mips/include/asm/mach-jazz/dma-coherence.h
@@ -27,11 +27,35 @@ static unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
return vdma_log2phys(dma_addr);
}
-static void plat_unmap_dma_mem(dma_addr_t dma_addr)
+static void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
{
vdma_free(dma_addr);
}
+static inline int plat_dma_supported(struct device *dev, u64 mask)
+{
+ /*
+ * we fall back to GFP_DMA when the mask isn't all 1s,
+ * so we can't guarantee allocations that must be
+ * within a tighter range than GFP_DMA..
+ */
+ if (mask < DMA_BIT_MASK(24))
+ return 0;
+
+ return 1;
+}
+
+static inline void plat_extra_sync_for_device(struct device *dev)
+{
+ return;
+}
+
+static inline int plat_dma_mapping_error(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ return 0;
+}
+
static inline int plat_device_is_coherent(struct device *dev)
{
return 0;
diff --git a/arch/mips/include/asm/mach-lemote/dma-coherence.h b/arch/mips/include/asm/mach-lemote/dma-coherence.h
index 7e91477..38fad7d 100644
--- a/arch/mips/include/asm/mach-lemote/dma-coherence.h
+++ b/arch/mips/include/asm/mach-lemote/dma-coherence.h
@@ -30,10 +30,34 @@ static inline unsigned long plat_dma_addr_to_phys(dma_addr_t dma_addr)
return dma_addr & 0x7fffffff;
}
-static inline void plat_unmap_dma_mem(dma_addr_t dma_addr)
+static inline void plat_unmap_dma_mem(struct device *dev, dma_addr_t dma_addr)
{
}
+static inline int plat_dma_supported(struct device *dev, u64 mask)
+{
+ /*
+ * we fall back to GFP_DMA when the mask isn't all 1s,
+ * so we can't guarantee allocations that must be
+ * within a tighter range than GFP_DMA..
+ */
+ if (mask < DMA_BIT_MASK(24))
+ return 0;
+
+ return 1;
+}
+
+static inline void plat_extra_sync_for_device(struct device *dev)
+{
+ return;
+}
+
+static inline int plat_dma_mapping_error(struct device *dev,
+ dma_addr_t dma_addr)
+{
+ return 0;
+}
+
static inline int plat_device_is_coherent(struct device *dev)
{
return 0;
diff --git a/arch/mips/include/asm/mipsregs.h b/arch/mips/include/asm/mipsregs.h
index 9316324..0417516 100644
--- a/arch/mips/include/asm/mipsregs.h
+++ b/arch/mips/include/asm/mipsregs.h
@@ -1000,6 +1000,26 @@ do { \
#define read_c0_ebase() __read_32bit_c0_register($15, 1)
#define write_c0_ebase(val) __write_32bit_c0_register($15, 1, val)
+
+/* Cavium OCTEON (cnMIPS) */
+#define read_c0_cvmcount() __read_ulong_c0_register($9, 6)
+#define write_c0_cvmcount(val) __write_ulong_c0_register($9, 6, val)
+
+#define read_c0_cvmctl() __read_64bit_c0_register($9, 7)
+#define write_c0_cvmctl(val) __write_64bit_c0_register($9, 7, val)
+
+#define read_c0_cvmmemctl() __read_64bit_c0_register($11, 7)
+#define write_c0_cvmmemctl(val) __write_64bit_c0_register($11, 7, val)
+/*
+ * The cacheerr registers are not standardized. On OCTEON, they are
+ * 64 bits wide.
+ */
+#define read_octeon_c0_icacheerr() __read_64bit_c0_register($27, 0)
+#define write_octeon_c0_icacheerr(val) __write_64bit_c0_register($27, 0, val)
+
+#define read_octeon_c0_dcacheerr() __read_64bit_c0_register($27, 1)
+#define write_octeon_c0_dcacheerr(val) __write_64bit_c0_register($27, 1, val)
+
/*
* Macros to access the floating point coprocessor control registers
*/
@@ -1008,6 +1028,8 @@ do { \
__asm__ __volatile__( \
".set\tpush\n\t" \
".set\treorder\n\t" \
+ /* gas fails to assemble cfc1 for some archs (octeon).*/ \
+ ".set\tmips1\n\t" \
"cfc1\t%0,"STR(source)"\n\t" \
".set\tpop" \
: "=r" (__res)); \
diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h
index e2e09b2..d94085a 100644
--- a/arch/mips/include/asm/module.h
+++ b/arch/mips/include/asm/module.h
@@ -116,6 +116,8 @@ search_module_dbetables(unsigned long addr)
#define MODULE_PROC_FAMILY "SB1 "
#elif defined CONFIG_CPU_LOONGSON2
#define MODULE_PROC_FAMILY "LOONGSON2 "
+#elif defined CONFIG_CPU_CAVIUM_OCTEON
+#define MODULE_PROC_FAMILY "OCTEON "
#else
#error MODULE_PROC_FAMILY undefined for your processor configuration
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-asm.h b/arch/mips/include/asm/octeon/cvmx-asm.h
new file mode 100644
index 0000000..b21d3fc
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-asm.h
@@ -0,0 +1,128 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ *
+ * This is file defines ASM primitives for the executive.
+ */
+#ifndef __CVMX_ASM_H__
+#define __CVMX_ASM_H__
+
+#include "octeon-model.h"
+
+/* other useful stuff */
+#define CVMX_SYNC asm volatile ("sync" : : : "memory")
+/* String version of SYNCW macro for using in inline asm constructs */
+#define CVMX_SYNCW_STR "syncw\nsyncw\n"
+#ifdef __OCTEON__
+
+/* Deprecated, will be removed in future release */
+#define CVMX_SYNCIO asm volatile ("nop")
+
+#define CVMX_SYNCIOBDMA asm volatile ("synciobdma" : : : "memory")
+
+/* Deprecated, will be removed in future release */
+#define CVMX_SYNCIOALL asm volatile ("nop")
+
+/*
+ * We actually use two syncw instructions in a row when we need a write
+ * memory barrier. This is because the CN3XXX series of Octeons have
+ * errata Core-401. This can cause a single syncw to not enforce
+ * ordering under very rare conditions. Even if it is rare, better safe
+ * than sorry.
+ */
+#define CVMX_SYNCW asm volatile ("syncw\n\tsyncw" : : : "memory")
+
+/*
+ * Define new sync instructions to be normal SYNC instructions for
+ * operating systems that use threads.
+ */
+#define CVMX_SYNCWS CVMX_SYNCW
+#define CVMX_SYNCS CVMX_SYNC
+#define CVMX_SYNCWS_STR CVMX_SYNCW_STR
+#else
+/*
+ * Not using a Cavium compiler, always use the slower sync so the
+ * assembler stays happy.
+ */
+/* Deprecated, will be removed in future release */
+#define CVMX_SYNCIO asm volatile ("nop")
+
+#define CVMX_SYNCIOBDMA asm volatile ("sync" : : : "memory")
+
+/* Deprecated, will be removed in future release */
+#define CVMX_SYNCIOALL asm volatile ("nop")
+
+#define CVMX_SYNCW asm volatile ("sync" : : : "memory")
+#define CVMX_SYNCWS CVMX_SYNCW
+#define CVMX_SYNCS CVMX_SYNC
+#define CVMX_SYNCWS_STR CVMX_SYNCW_STR
+#endif
+
+/*
+ * CVMX_PREPARE_FOR_STORE makes each byte of the block unpredictable
+ * (actually old value or zero) until that byte is stored to (by this or
+ * another processor. Note that the value of each byte is not only
+ * unpredictable, but may also change again - up until the point when one
+ * of the cores stores to the byte.
+ */
+#define CVMX_PREPARE_FOR_STORE(address, offset) \
+ asm volatile ("pref 30, " CVMX_TMP_STR(offset) "(%[rbase])" : : \
+ [rbase] "d" (address))
+/*
+ * This is a command headed to the L2 controller to tell it to clear
+ * its dirty bit for a block. Basically, SW is telling HW that the
+ * current version of the block will not be used.
+ */
+#define CVMX_DONT_WRITE_BACK(address, offset) \
+ asm volatile ("pref 29, " CVMX_TMP_STR(offset) "(%[rbase])" : : \
+ [rbase] "d" (address))
+
+/* flush stores, invalidate entire icache */
+#define CVMX_ICACHE_INVALIDATE \
+ { CVMX_SYNC; asm volatile ("synci 0($0)" : : ); }
+
+/* flush stores, invalidate entire icache */
+#define CVMX_ICACHE_INVALIDATE2 \
+ { CVMX_SYNC; asm volatile ("cache 0, 0($0)" : : ); }
+
+/* complete prefetches, invalidate entire dcache */
+#define CVMX_DCACHE_INVALIDATE \
+ { CVMX_SYNC; asm volatile ("cache 9, 0($0)" : : ); }
+
+
+#define CVMX_POP(result, input) \
+ asm ("pop %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input))
+#define CVMX_DPOP(result, input) \
+ asm ("dpop %[rd],%[rs]" : [rd] "=d" (result) : [rs] "d" (input))
+
+/* some new cop0-like stuff */
+#define CVMX_RDHWR(result, regstr) \
+ asm volatile ("rdhwr %[rt],$" CVMX_TMP_STR(regstr) : [rt] "=d" (result))
+#define CVMX_RDHWRNV(result, regstr) \
+ asm ("rdhwr %[rt],$" CVMX_TMP_STR(regstr) : [rt] "=d" (result))
+#endif /* __CVMX_ASM_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-bootinfo.h b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
new file mode 100644
index 0000000..692989a
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h
@@ -0,0 +1,262 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Header file containing the ABI with the bootloader.
+ */
+
+#ifndef __CVMX_BOOTINFO_H__
+#define __CVMX_BOOTINFO_H__
+
+/*
+ * Current major and minor versions of the CVMX bootinfo block that is
+ * passed from the bootloader to the application. This is versioned
+ * so that applications can properly handle multiple bootloader
+ * versions.
+ */
+#define CVMX_BOOTINFO_MAJ_VER 1
+#define CVMX_BOOTINFO_MIN_VER 2
+
+#if (CVMX_BOOTINFO_MAJ_VER == 1)
+#define CVMX_BOOTINFO_OCTEON_SERIAL_LEN 20
+/*
+ * This structure is populated by the bootloader. For binary
+ * compatibility the only changes that should be made are
+ * adding members to the end of the structure, and the minor
+ * version should be incremented at that time.
+ * If an incompatible change is made, the major version
+ * must be incremented, and the minor version should be reset
+ * to 0.
+ */
+struct cvmx_bootinfo {
+ uint32_t major_version;
+ uint32_t minor_version;
+
+ uint64_t stack_top;
+ uint64_t heap_base;
+ uint64_t heap_end;
+ uint64_t desc_vaddr;
+
+ uint32_t exception_base_addr;
+ uint32_t stack_size;
+ uint32_t flags;
+ uint32_t core_mask;
+ /* DRAM size in megabytes */
+ uint32_t dram_size;
+ /* physical address of free memory descriptor block*/
+ uint32_t phy_mem_desc_addr;
+ /* used to pass flags from app to debugger */
+ uint32_t debugger_flags_base_addr;
+
+ /* CPU clock speed, in hz */
+ uint32_t eclock_hz;
+
+ /* DRAM clock speed, in hz */
+ uint32_t dclock_hz;
+
+ uint32_t reserved0;
+ uint16_t board_type;
+ uint8_t board_rev_major;
+ uint8_t board_rev_minor;
+ uint16_t reserved1;
+ uint8_t reserved2;
+ uint8_t reserved3;
+ char board_serial_number[CVMX_BOOTINFO_OCTEON_SERIAL_LEN];
+ uint8_t mac_addr_base[6];
+ uint8_t mac_addr_count;
+#if (CVMX_BOOTINFO_MIN_VER >= 1)
+ /*
+ * Several boards support compact flash on the Octeon boot
+ * bus. The CF memory spaces may be mapped to different
+ * addresses on different boards. These are the physical
+ * addresses, so care must be taken to use the correct
+ * XKPHYS/KSEG0 addressing depending on the application's
+ * ABI. These values will be 0 if CF is not present.
+ */
+ uint64_t compact_flash_common_base_addr;
+ uint64_t compact_flash_attribute_base_addr;
+ /*
+ * Base address of the LED display (as on EBT3000 board)
+ * This will be 0 if LED display not present.
+ */
+ uint64_t led_display_base_addr;
+#endif
+#if (CVMX_BOOTINFO_MIN_VER >= 2)
+ /* DFA reference clock in hz (if applicable)*/
+ uint32_t dfa_ref_clock_hz;
+
+ /*
+ * flags indicating various configuration options. These
+ * flags supercede the 'flags' variable and should be used
+ * instead if available.
+ */
+ uint32_t config_flags;
+#endif
+
+};
+
+#define CVMX_BOOTINFO_CFG_FLAG_PCI_HOST (1ull << 0)
+#define CVMX_BOOTINFO_CFG_FLAG_PCI_TARGET (1ull << 1)
+#define CVMX_BOOTINFO_CFG_FLAG_DEBUG (1ull << 2)
+#define CVMX_BOOTINFO_CFG_FLAG_NO_MAGIC (1ull << 3)
+/* This flag is set if the TLB mappings are not contained in the
+ * 0x10000000 - 0x20000000 boot bus region. */
+#define CVMX_BOOTINFO_CFG_FLAG_OVERSIZE_TLB_MAPPING (1ull << 4)
+#define CVMX_BOOTINFO_CFG_FLAG_BREAK (1ull << 5)
+
+#endif /* (CVMX_BOOTINFO_MAJ_VER == 1) */
+
+/* Type defines for board and chip types */
+enum cvmx_board_types_enum {
+ CVMX_BOARD_TYPE_NULL = 0,
+ CVMX_BOARD_TYPE_SIM = 1,
+ CVMX_BOARD_TYPE_EBT3000 = 2,
+ CVMX_BOARD_TYPE_KODAMA = 3,
+ CVMX_BOARD_TYPE_NIAGARA = 4,
+ CVMX_BOARD_TYPE_NAC38 = 5, /* formerly NAO38 */
+ CVMX_BOARD_TYPE_THUNDER = 6,
+ CVMX_BOARD_TYPE_TRANTOR = 7,
+ CVMX_BOARD_TYPE_EBH3000 = 8,
+ CVMX_BOARD_TYPE_EBH3100 = 9,
+ CVMX_BOARD_TYPE_HIKARI = 10,
+ CVMX_BOARD_TYPE_CN3010_EVB_HS5 = 11,
+ CVMX_BOARD_TYPE_CN3005_EVB_HS5 = 12,
+ CVMX_BOARD_TYPE_KBP = 13,
+ /* Deprecated, CVMX_BOARD_TYPE_CN3010_EVB_HS5 supports the CN3020 */
+ CVMX_BOARD_TYPE_CN3020_EVB_HS5 = 14,
+ CVMX_BOARD_TYPE_EBT5800 = 15,
+ CVMX_BOARD_TYPE_NICPRO2 = 16,
+ CVMX_BOARD_TYPE_EBH5600 = 17,
+ CVMX_BOARD_TYPE_EBH5601 = 18,
+ CVMX_BOARD_TYPE_EBH5200 = 19,
+ CVMX_BOARD_TYPE_BBGW_REF = 20,
+ CVMX_BOARD_TYPE_NIC_XLE_4G = 21,
+ CVMX_BOARD_TYPE_EBT5600 = 22,
+ CVMX_BOARD_TYPE_EBH5201 = 23,
+ CVMX_BOARD_TYPE_MAX,
+
+ /*
+ * The range from CVMX_BOARD_TYPE_MAX to
+ * CVMX_BOARD_TYPE_CUST_DEFINED_MIN is reserved for future
+ * SDK use.
+ */
+
+ /*
+ * Set aside a range for customer boards. These numbers are managed
+ * by Cavium.
+ */
+ CVMX_BOARD_TYPE_CUST_DEFINED_MIN = 10000,
+ CVMX_BOARD_TYPE_CUST_WSX16 = 10001,
+ CVMX_BOARD_TYPE_CUST_NS0216 = 10002,
+ CVMX_BOARD_TYPE_CUST_NB5 = 10003,
+ CVMX_BOARD_TYPE_CUST_WMR500 = 10004,
+ CVMX_BOARD_TYPE_CUST_DEFINED_MAX = 20000,
+
+ /*
+ * Set aside a range for customer private use. The SDK won't
+ * use any numbers in this range.
+ */
+ CVMX_BOARD_TYPE_CUST_PRIVATE_MIN = 20001,
+ CVMX_BOARD_TYPE_CUST_PRIVATE_MAX = 30000,
+
+ /* The remaining range is reserved for future use. */
+};
+
+enum cvmx_chip_types_enum {
+ CVMX_CHIP_TYPE_NULL = 0,
+ CVMX_CHIP_SIM_TYPE_DEPRECATED = 1,
+ CVMX_CHIP_TYPE_OCTEON_SAMPLE = 2,
+ CVMX_CHIP_TYPE_MAX,
+};
+
+/* Compatability alias for NAC38 name change, planned to be removed
+ * from SDK 1.7 */
+#define CVMX_BOARD_TYPE_NAO38 CVMX_BOARD_TYPE_NAC38
+
+/* Functions to return string based on type */
+#define ENUM_BRD_TYPE_CASE(x) \
+ case x: return(#x + 16); /* Skip CVMX_BOARD_TYPE_ */
+static inline const char *cvmx_board_type_to_string(enum
+ cvmx_board_types_enum type)
+{
+ switch (type) {
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NULL)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_SIM)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBT3000)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_KODAMA)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NIAGARA)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NAC38)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_THUNDER)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_TRANTOR)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH3000)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH3100)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_HIKARI)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CN3010_EVB_HS5)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CN3005_EVB_HS5)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_KBP)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CN3020_EVB_HS5)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBT5800)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NICPRO2)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5600)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5601)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5200)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_BBGW_REF)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_NIC_XLE_4G)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBT5600)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_EBH5201)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_MAX)
+
+ /* Customer boards listed here */
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DEFINED_MIN)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_WSX16)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_NS0216)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_NB5)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_WMR500)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_DEFINED_MAX)
+
+ /* Customer private range */
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MIN)
+ ENUM_BRD_TYPE_CASE(CVMX_BOARD_TYPE_CUST_PRIVATE_MAX)
+ }
+ return "Unsupported Board";
+}
+
+#define ENUM_CHIP_TYPE_CASE(x) \
+ case x: return(#x + 15); /* Skip CVMX_CHIP_TYPE */
+static inline const char *cvmx_chip_type_to_string(enum
+ cvmx_chip_types_enum type)
+{
+ switch (type) {
+ ENUM_CHIP_TYPE_CASE(CVMX_CHIP_TYPE_NULL)
+ ENUM_CHIP_TYPE_CASE(CVMX_CHIP_SIM_TYPE_DEPRECATED)
+ ENUM_CHIP_TYPE_CASE(CVMX_CHIP_TYPE_OCTEON_SAMPLE)
+ ENUM_CHIP_TYPE_CASE(CVMX_CHIP_TYPE_MAX)
+ }
+ return "Unsupported Chip";
+}
+
+#endif /* __CVMX_BOOTINFO_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-bootmem.h b/arch/mips/include/asm/octeon/cvmx-bootmem.h
new file mode 100644
index 0000000..1cbe4b5
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-bootmem.h
@@ -0,0 +1,288 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Simple allocate only memory allocator. Used to allocate memory at
+ * application start time.
+ */
+
+#ifndef __CVMX_BOOTMEM_H__
+#define __CVMX_BOOTMEM_H__
+/* Must be multiple of 8, changing breaks ABI */
+#define CVMX_BOOTMEM_NAME_LEN 128
+
+/* Can change without breaking ABI */
+#define CVMX_BOOTMEM_NUM_NAMED_BLOCKS 64
+
+/* minimum alignment of bootmem alloced blocks */
+#define CVMX_BOOTMEM_ALIGNMENT_SIZE (16ull)
+
+/* Flags for cvmx_bootmem_phy_mem* functions */
+/* Allocate from end of block instead of beginning */
+#define CVMX_BOOTMEM_FLAG_END_ALLOC (1 << 0)
+
+/* Don't do any locking. */
+#define CVMX_BOOTMEM_FLAG_NO_LOCKING (1 << 1)
+
+/* First bytes of each free physical block of memory contain this structure,
+ * which is used to maintain the free memory list. Since the bootloader is
+ * only 32 bits, there is a union providing 64 and 32 bit versions. The
+ * application init code converts addresses to 64 bit addresses before the
+ * application starts.
+ */
+struct cvmx_bootmem_block_header {
+ /*
+ * Note: these are referenced from assembly routines in the
+ * bootloader, so this structure should not be changed
+ * without changing those routines as well.
+ */
+ uint64_t next_block_addr;
+ uint64_t size;
+
+};
+
+/*
+ * Structure for named memory blocks. Number of descriptors available
+ * can be changed without affecting compatiblity, but name length
+ * changes require a bump in the bootmem descriptor version Note: This
+ * structure must be naturally 64 bit aligned, as a single memory
+ * image will be used by both 32 and 64 bit programs.
+ */
+struct cvmx_bootmem_named_block_desc {
+ /* Base address of named block */
+ uint64_t base_addr;
+ /*
+ * Size actually allocated for named block (may differ from
+ * requested).
+ */
+ uint64_t size;
+ /* name of named block */
+ char name[CVMX_BOOTMEM_NAME_LEN];
+};
+
+/* Current descriptor versions */
+/* CVMX bootmem descriptor major version */
+#define CVMX_BOOTMEM_DESC_MAJ_VER 3
+
+/* CVMX bootmem descriptor minor version */
+#define CVMX_BOOTMEM_DESC_MIN_VER 0
+
+/* First three members of cvmx_bootmem_desc_t are left in original
+ * positions for backwards compatibility.
+ */
+struct cvmx_bootmem_desc {
+ /* spinlock to control access to list */
+ uint32_t lock;
+ /* flags for indicating various conditions */
+ uint32_t flags;
+ uint64_t head_addr;
+
+ /* Incremented when incompatible changes made */
+ uint32_t major_version;
+
+ /*
+ * Incremented changed when compatible changes made, reset to
+ * zero when major incremented.
+ */
+ uint32_t minor_version;
+
+ uint64_t app_data_addr;
+ uint64_t app_data_size;
+
+ /* number of elements in named blocks array */
+ uint32_t named_block_num_blocks;
+
+ /* length of name array in bootmem blocks */
+ uint32_t named_block_name_len;
+ /* address of named memory block descriptors */
+ uint64_t named_block_array_addr;
+
+};
+
+/**
+ * Initialize the boot alloc memory structures. This is
+ * normally called inside of cvmx_user_app_init()
+ *
+ * @mem_desc_ptr: Address of the free memory list
+ */
+extern int cvmx_bootmem_init(void *mem_desc_ptr);
+
+/**
+ * Allocate a block of memory from the free list that was passed
+ * to the application by the bootloader.
+ * This is an allocate-only algorithm, so freeing memory is not possible.
+ *
+ * @size: Size in bytes of block to allocate
+ * @alignment: Alignment required - must be power of 2
+ *
+ * Returns pointer to block of memory, NULL on error
+ */
+extern void *cvmx_bootmem_alloc(uint64_t size, uint64_t alignment);
+
+/**
+ * Allocate a block of memory from the free list that was
+ * passed to the application by the bootloader at a specific
+ * address. This is an allocate-only algorithm, so
+ * freeing memory is not possible. Allocation will fail if
+ * memory cannot be allocated at the specified address.
+ *
+ * @size: Size in bytes of block to allocate
+ * @address: Physical address to allocate memory at. If this memory is not
+ * available, the allocation fails.
+ * @alignment: Alignment required - must be power of 2
+ * Returns pointer to block of memory, NULL on error
+ */
+extern void *cvmx_bootmem_alloc_address(uint64_t size, uint64_t address,
+ uint64_t alignment);
+
+/**
+ * Allocate a block of memory from the free list that was
+ * passed to the application by the bootloader within a specified
+ * address range. This is an allocate-only algorithm, so
+ * freeing memory is not possible. Allocation will fail if
+ * memory cannot be allocated in the requested range.
+ *
+ * @size: Size in bytes of block to allocate
+ * @min_addr: defines the minimum address of the range
+ * @max_addr: defines the maximum address of the range
+ * @alignment: Alignment required - must be power of 2
+ * Returns pointer to block of memory, NULL on error
+ */
+extern void *cvmx_bootmem_alloc_range(uint64_t size, uint64_t alignment,
+ uint64_t min_addr, uint64_t max_addr);
+
+/**
+ * Frees a previously allocated named bootmem block.
+ *
+ * @name: name of block to free
+ *
+ * Returns 0 on failure,
+ * !0 on success
+ */
+extern int cvmx_bootmem_free_named(char *name);
+
+/**
+ * Finds a named bootmem block by name.
+ *
+ * @name: name of block to free
+ *
+ * Returns pointer to named block descriptor on success
+ * 0 on failure
+ */
+struct cvmx_bootmem_named_block_desc *cvmx_bootmem_find_named_block(char *name);
+
+/**
+ * Allocates a block of physical memory from the free list, at
+ * (optional) requested address and alignment.
+ *
+ * @req_size: size of region to allocate. All requests are rounded up
+ * to be a multiple CVMX_BOOTMEM_ALIGNMENT_SIZE bytes size
+ *
+ * @address_min: Minimum address that block can occupy.
+ *
+ * @address_max: Specifies the maximum address_min (inclusive) that
+ * the allocation can use.
+ *
+ * @alignment: Requested alignment of the block. If this alignment
+ * cannot be met, the allocation fails. This must be a
+ * power of 2. (Note: Alignment of
+ * CVMX_BOOTMEM_ALIGNMENT_SIZE bytes is required, and
+ * internally enforced. Requested alignments of less than
+ * CVMX_BOOTMEM_ALIGNMENT_SIZE are set to
+ * CVMX_BOOTMEM_ALIGNMENT_SIZE.)
+ *
+ * @flags: Flags to control options for the allocation.
+ *
+ * Returns physical address of block allocated, or -1 on failure
+ */
+int64_t cvmx_bootmem_phy_alloc(uint64_t req_size, uint64_t address_min,
+ uint64_t address_max, uint64_t alignment,
+ uint32_t flags);
+
+/**
+ * Finds a named memory block by name.
+ * Also used for finding an unused entry in the named block table.
+ *
+ * @name: Name of memory block to find. If NULL pointer given, then
+ * finds unused descriptor, if available.
+ *
+ * @flags: Flags to control options for the allocation.
+ *
+ * Returns Pointer to memory block descriptor, NULL if not found.
+ * If NULL returned when name parameter is NULL, then no memory
+ * block descriptors are available.
+ */
+struct cvmx_bootmem_named_block_desc *
+cvmx_bootmem_phy_named_block_find(char *name, uint32_t flags);
+
+/**
+ * Frees a named block.
+ *
+ * @name: name of block to free
+ * @flags: flags for passing options
+ *
+ * Returns 0 on failure
+ * 1 on success
+ */
+int cvmx_bootmem_phy_named_block_free(char *name, uint32_t flags);
+
+/**
+ * Frees a block to the bootmem allocator list. This must
+ * be used with care, as the size provided must match the size
+ * of the block that was allocated, or the list will become
+ * corrupted.
+ *
+ * IMPORTANT: This is only intended to be used as part of named block
+ * frees and initial population of the free memory list.
+ * *
+ *
+ * @phy_addr: physical address of block
+ * @size: size of block in bytes.
+ * @flags: flags for passing options
+ *
+ * Returns 1 on success,
+ * 0 on failure
+ */
+int __cvmx_bootmem_phy_free(uint64_t phy_addr, uint64_t size, uint32_t flags);
+
+/**
+ * Locks the bootmem allocator. This is useful in certain situations
+ * where multiple allocations must be made without being interrupted.
+ * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag.
+ *
+ */
+void cvmx_bootmem_lock(void);
+
+/**
+ * Unlocks the bootmem allocator. This is useful in certain situations
+ * where multiple allocations must be made without being interrupted.
+ * This should be used with the CVMX_BOOTMEM_FLAG_NO_LOCKING flag.
+ *
+ */
+void cvmx_bootmem_unlock(void);
+
+#endif /* __CVMX_BOOTMEM_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-ciu-defs.h b/arch/mips/include/asm/octeon/cvmx-ciu-defs.h
new file mode 100644
index 0000000..f8f05b7
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-ciu-defs.h
@@ -0,0 +1,1616 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_CIU_DEFS_H__
+#define __CVMX_CIU_DEFS_H__
+
+#define CVMX_CIU_BIST \
+ CVMX_ADD_IO_SEG(0x0001070000000730ull)
+#define CVMX_CIU_DINT \
+ CVMX_ADD_IO_SEG(0x0001070000000720ull)
+#define CVMX_CIU_FUSE \
+ CVMX_ADD_IO_SEG(0x0001070000000728ull)
+#define CVMX_CIU_GSTOP \
+ CVMX_ADD_IO_SEG(0x0001070000000710ull)
+#define CVMX_CIU_INTX_EN0(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000000200ull + (((offset) & 63) * 16))
+#define CVMX_CIU_INTX_EN0_W1C(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000002200ull + (((offset) & 63) * 16))
+#define CVMX_CIU_INTX_EN0_W1S(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000006200ull + (((offset) & 63) * 16))
+#define CVMX_CIU_INTX_EN1(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000000208ull + (((offset) & 63) * 16))
+#define CVMX_CIU_INTX_EN1_W1C(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000002208ull + (((offset) & 63) * 16))
+#define CVMX_CIU_INTX_EN1_W1S(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000006208ull + (((offset) & 63) * 16))
+#define CVMX_CIU_INTX_EN4_0(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000000C80ull + (((offset) & 15) * 16))
+#define CVMX_CIU_INTX_EN4_0_W1C(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000002C80ull + (((offset) & 15) * 16))
+#define CVMX_CIU_INTX_EN4_0_W1S(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000006C80ull + (((offset) & 15) * 16))
+#define CVMX_CIU_INTX_EN4_1(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000000C88ull + (((offset) & 15) * 16))
+#define CVMX_CIU_INTX_EN4_1_W1C(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000002C88ull + (((offset) & 15) * 16))
+#define CVMX_CIU_INTX_EN4_1_W1S(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000006C88ull + (((offset) & 15) * 16))
+#define CVMX_CIU_INTX_SUM0(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000000000ull + (((offset) & 63) * 8))
+#define CVMX_CIU_INTX_SUM4(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000000C00ull + (((offset) & 15) * 8))
+#define CVMX_CIU_INT_SUM1 \
+ CVMX_ADD_IO_SEG(0x0001070000000108ull)
+#define CVMX_CIU_MBOX_CLRX(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000000680ull + (((offset) & 15) * 8))
+#define CVMX_CIU_MBOX_SETX(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000000600ull + (((offset) & 15) * 8))
+#define CVMX_CIU_NMI \
+ CVMX_ADD_IO_SEG(0x0001070000000718ull)
+#define CVMX_CIU_PCI_INTA \
+ CVMX_ADD_IO_SEG(0x0001070000000750ull)
+#define CVMX_CIU_PP_DBG \
+ CVMX_ADD_IO_SEG(0x0001070000000708ull)
+#define CVMX_CIU_PP_POKEX(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000000580ull + (((offset) & 15) * 8))
+#define CVMX_CIU_PP_RST \
+ CVMX_ADD_IO_SEG(0x0001070000000700ull)
+#define CVMX_CIU_QLM_DCOK \
+ CVMX_ADD_IO_SEG(0x0001070000000760ull)
+#define CVMX_CIU_QLM_JTGC \
+ CVMX_ADD_IO_SEG(0x0001070000000768ull)
+#define CVMX_CIU_QLM_JTGD \
+ CVMX_ADD_IO_SEG(0x0001070000000770ull)
+#define CVMX_CIU_SOFT_BIST \
+ CVMX_ADD_IO_SEG(0x0001070000000738ull)
+#define CVMX_CIU_SOFT_PRST \
+ CVMX_ADD_IO_SEG(0x0001070000000748ull)
+#define CVMX_CIU_SOFT_PRST1 \
+ CVMX_ADD_IO_SEG(0x0001070000000758ull)
+#define CVMX_CIU_SOFT_RST \
+ CVMX_ADD_IO_SEG(0x0001070000000740ull)
+#define CVMX_CIU_TIMX(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000000480ull + (((offset) & 3) * 8))
+#define CVMX_CIU_WDOGX(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000000500ull + (((offset) & 15) * 8))
+
+union cvmx_ciu_bist {
+ uint64_t u64;
+ struct cvmx_ciu_bist_s {
+ uint64_t reserved_4_63:60;
+ uint64_t bist:4;
+ } s;
+ struct cvmx_ciu_bist_s cn30xx;
+ struct cvmx_ciu_bist_s cn31xx;
+ struct cvmx_ciu_bist_s cn38xx;
+ struct cvmx_ciu_bist_s cn38xxp2;
+ struct cvmx_ciu_bist_cn50xx {
+ uint64_t reserved_2_63:62;
+ uint64_t bist:2;
+ } cn50xx;
+ struct cvmx_ciu_bist_cn52xx {
+ uint64_t reserved_3_63:61;
+ uint64_t bist:3;
+ } cn52xx;
+ struct cvmx_ciu_bist_cn52xx cn52xxp1;
+ struct cvmx_ciu_bist_s cn56xx;
+ struct cvmx_ciu_bist_s cn56xxp1;
+ struct cvmx_ciu_bist_s cn58xx;
+ struct cvmx_ciu_bist_s cn58xxp1;
+};
+
+union cvmx_ciu_dint {
+ uint64_t u64;
+ struct cvmx_ciu_dint_s {
+ uint64_t reserved_16_63:48;
+ uint64_t dint:16;
+ } s;
+ struct cvmx_ciu_dint_cn30xx {
+ uint64_t reserved_1_63:63;
+ uint64_t dint:1;
+ } cn30xx;
+ struct cvmx_ciu_dint_cn31xx {
+ uint64_t reserved_2_63:62;
+ uint64_t dint:2;
+ } cn31xx;
+ struct cvmx_ciu_dint_s cn38xx;
+ struct cvmx_ciu_dint_s cn38xxp2;
+ struct cvmx_ciu_dint_cn31xx cn50xx;
+ struct cvmx_ciu_dint_cn52xx {
+ uint64_t reserved_4_63:60;
+ uint64_t dint:4;
+ } cn52xx;
+ struct cvmx_ciu_dint_cn52xx cn52xxp1;
+ struct cvmx_ciu_dint_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t dint:12;
+ } cn56xx;
+ struct cvmx_ciu_dint_cn56xx cn56xxp1;
+ struct cvmx_ciu_dint_s cn58xx;
+ struct cvmx_ciu_dint_s cn58xxp1;
+};
+
+union cvmx_ciu_fuse {
+ uint64_t u64;
+ struct cvmx_ciu_fuse_s {
+ uint64_t reserved_16_63:48;
+ uint64_t fuse:16;
+ } s;
+ struct cvmx_ciu_fuse_cn30xx {
+ uint64_t reserved_1_63:63;
+ uint64_t fuse:1;
+ } cn30xx;
+ struct cvmx_ciu_fuse_cn31xx {
+ uint64_t reserved_2_63:62;
+ uint64_t fuse:2;
+ } cn31xx;
+ struct cvmx_ciu_fuse_s cn38xx;
+ struct cvmx_ciu_fuse_s cn38xxp2;
+ struct cvmx_ciu_fuse_cn31xx cn50xx;
+ struct cvmx_ciu_fuse_cn52xx {
+ uint64_t reserved_4_63:60;
+ uint64_t fuse:4;
+ } cn52xx;
+ struct cvmx_ciu_fuse_cn52xx cn52xxp1;
+ struct cvmx_ciu_fuse_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t fuse:12;
+ } cn56xx;
+ struct cvmx_ciu_fuse_cn56xx cn56xxp1;
+ struct cvmx_ciu_fuse_s cn58xx;
+ struct cvmx_ciu_fuse_s cn58xxp1;
+};
+
+union cvmx_ciu_gstop {
+ uint64_t u64;
+ struct cvmx_ciu_gstop_s {
+ uint64_t reserved_1_63:63;
+ uint64_t gstop:1;
+ } s;
+ struct cvmx_ciu_gstop_s cn30xx;
+ struct cvmx_ciu_gstop_s cn31xx;
+ struct cvmx_ciu_gstop_s cn38xx;
+ struct cvmx_ciu_gstop_s cn38xxp2;
+ struct cvmx_ciu_gstop_s cn50xx;
+ struct cvmx_ciu_gstop_s cn52xx;
+ struct cvmx_ciu_gstop_s cn52xxp1;
+ struct cvmx_ciu_gstop_s cn56xx;
+ struct cvmx_ciu_gstop_s cn56xxp1;
+ struct cvmx_ciu_gstop_s cn58xx;
+ struct cvmx_ciu_gstop_s cn58xxp1;
+};
+
+union cvmx_ciu_intx_en0 {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en0_s {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } s;
+ struct cvmx_ciu_intx_en0_cn30xx {
+ uint64_t reserved_59_63:5;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_47_47:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn30xx;
+ struct cvmx_ciu_intx_en0_cn31xx {
+ uint64_t reserved_59_63:5;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn31xx;
+ struct cvmx_ciu_intx_en0_cn38xx {
+ uint64_t reserved_56_63:8;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn38xx;
+ struct cvmx_ciu_intx_en0_cn38xx cn38xxp2;
+ struct cvmx_ciu_intx_en0_cn30xx cn50xx;
+ struct cvmx_ciu_intx_en0_cn52xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn52xx;
+ struct cvmx_ciu_intx_en0_cn52xx cn52xxp1;
+ struct cvmx_ciu_intx_en0_cn56xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn56xx;
+ struct cvmx_ciu_intx_en0_cn56xx cn56xxp1;
+ struct cvmx_ciu_intx_en0_cn38xx cn58xx;
+ struct cvmx_ciu_intx_en0_cn38xx cn58xxp1;
+};
+
+union cvmx_ciu_intx_en0_w1c {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en0_w1c_s {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } s;
+ struct cvmx_ciu_intx_en0_w1c_cn52xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn52xx;
+ struct cvmx_ciu_intx_en0_w1c_s cn56xx;
+ struct cvmx_ciu_intx_en0_w1c_cn58xx {
+ uint64_t reserved_56_63:8;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn58xx;
+};
+
+union cvmx_ciu_intx_en0_w1s {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en0_w1s_s {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } s;
+ struct cvmx_ciu_intx_en0_w1s_cn52xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn52xx;
+ struct cvmx_ciu_intx_en0_w1s_s cn56xx;
+ struct cvmx_ciu_intx_en0_w1s_cn58xx {
+ uint64_t reserved_56_63:8;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn58xx;
+};
+
+union cvmx_ciu_intx_en1 {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en1_s {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t wdog:16;
+ } s;
+ struct cvmx_ciu_intx_en1_cn30xx {
+ uint64_t reserved_1_63:63;
+ uint64_t wdog:1;
+ } cn30xx;
+ struct cvmx_ciu_intx_en1_cn31xx {
+ uint64_t reserved_2_63:62;
+ uint64_t wdog:2;
+ } cn31xx;
+ struct cvmx_ciu_intx_en1_cn38xx {
+ uint64_t reserved_16_63:48;
+ uint64_t wdog:16;
+ } cn38xx;
+ struct cvmx_ciu_intx_en1_cn38xx cn38xxp2;
+ struct cvmx_ciu_intx_en1_cn31xx cn50xx;
+ struct cvmx_ciu_intx_en1_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xx;
+ struct cvmx_ciu_intx_en1_cn52xxp1 {
+ uint64_t reserved_19_63:45;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xxp1;
+ struct cvmx_ciu_intx_en1_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t wdog:12;
+ } cn56xx;
+ struct cvmx_ciu_intx_en1_cn56xx cn56xxp1;
+ struct cvmx_ciu_intx_en1_cn38xx cn58xx;
+ struct cvmx_ciu_intx_en1_cn38xx cn58xxp1;
+};
+
+union cvmx_ciu_intx_en1_w1c {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en1_w1c_s {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t wdog:16;
+ } s;
+ struct cvmx_ciu_intx_en1_w1c_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xx;
+ struct cvmx_ciu_intx_en1_w1c_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t wdog:12;
+ } cn56xx;
+ struct cvmx_ciu_intx_en1_w1c_cn58xx {
+ uint64_t reserved_16_63:48;
+ uint64_t wdog:16;
+ } cn58xx;
+};
+
+union cvmx_ciu_intx_en1_w1s {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en1_w1s_s {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t wdog:16;
+ } s;
+ struct cvmx_ciu_intx_en1_w1s_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xx;
+ struct cvmx_ciu_intx_en1_w1s_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t wdog:12;
+ } cn56xx;
+ struct cvmx_ciu_intx_en1_w1s_cn58xx {
+ uint64_t reserved_16_63:48;
+ uint64_t wdog:16;
+ } cn58xx;
+};
+
+union cvmx_ciu_intx_en4_0 {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en4_0_s {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } s;
+ struct cvmx_ciu_intx_en4_0_cn50xx {
+ uint64_t reserved_59_63:5;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_47_47:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn50xx;
+ struct cvmx_ciu_intx_en4_0_cn52xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn52xx;
+ struct cvmx_ciu_intx_en4_0_cn52xx cn52xxp1;
+ struct cvmx_ciu_intx_en4_0_cn56xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn56xx;
+ struct cvmx_ciu_intx_en4_0_cn56xx cn56xxp1;
+ struct cvmx_ciu_intx_en4_0_cn58xx {
+ uint64_t reserved_56_63:8;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn58xx;
+ struct cvmx_ciu_intx_en4_0_cn58xx cn58xxp1;
+};
+
+union cvmx_ciu_intx_en4_0_w1c {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en4_0_w1c_s {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } s;
+ struct cvmx_ciu_intx_en4_0_w1c_cn52xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn52xx;
+ struct cvmx_ciu_intx_en4_0_w1c_s cn56xx;
+ struct cvmx_ciu_intx_en4_0_w1c_cn58xx {
+ uint64_t reserved_56_63:8;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn58xx;
+};
+
+union cvmx_ciu_intx_en4_0_w1s {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en4_0_w1s_s {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } s;
+ struct cvmx_ciu_intx_en4_0_w1s_cn52xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn52xx;
+ struct cvmx_ciu_intx_en4_0_w1s_s cn56xx;
+ struct cvmx_ciu_intx_en4_0_w1s_cn58xx {
+ uint64_t reserved_56_63:8;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t reserved_44_44:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn58xx;
+};
+
+union cvmx_ciu_intx_en4_1 {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en4_1_s {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t wdog:16;
+ } s;
+ struct cvmx_ciu_intx_en4_1_cn50xx {
+ uint64_t reserved_2_63:62;
+ uint64_t wdog:2;
+ } cn50xx;
+ struct cvmx_ciu_intx_en4_1_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xx;
+ struct cvmx_ciu_intx_en4_1_cn52xxp1 {
+ uint64_t reserved_19_63:45;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xxp1;
+ struct cvmx_ciu_intx_en4_1_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t wdog:12;
+ } cn56xx;
+ struct cvmx_ciu_intx_en4_1_cn56xx cn56xxp1;
+ struct cvmx_ciu_intx_en4_1_cn58xx {
+ uint64_t reserved_16_63:48;
+ uint64_t wdog:16;
+ } cn58xx;
+ struct cvmx_ciu_intx_en4_1_cn58xx cn58xxp1;
+};
+
+union cvmx_ciu_intx_en4_1_w1c {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en4_1_w1c_s {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t wdog:16;
+ } s;
+ struct cvmx_ciu_intx_en4_1_w1c_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xx;
+ struct cvmx_ciu_intx_en4_1_w1c_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t wdog:12;
+ } cn56xx;
+ struct cvmx_ciu_intx_en4_1_w1c_cn58xx {
+ uint64_t reserved_16_63:48;
+ uint64_t wdog:16;
+ } cn58xx;
+};
+
+union cvmx_ciu_intx_en4_1_w1s {
+ uint64_t u64;
+ struct cvmx_ciu_intx_en4_1_w1s_s {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t wdog:16;
+ } s;
+ struct cvmx_ciu_intx_en4_1_w1s_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xx;
+ struct cvmx_ciu_intx_en4_1_w1s_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t wdog:12;
+ } cn56xx;
+ struct cvmx_ciu_intx_en4_1_w1s_cn58xx {
+ uint64_t reserved_16_63:48;
+ uint64_t wdog:16;
+ } cn58xx;
+};
+
+union cvmx_ciu_intx_sum0 {
+ uint64_t u64;
+ struct cvmx_ciu_intx_sum0_s {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } s;
+ struct cvmx_ciu_intx_sum0_cn30xx {
+ uint64_t reserved_59_63:5;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_47_47:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn30xx;
+ struct cvmx_ciu_intx_sum0_cn31xx {
+ uint64_t reserved_59_63:5;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn31xx;
+ struct cvmx_ciu_intx_sum0_cn38xx {
+ uint64_t reserved_56_63:8;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn38xx;
+ struct cvmx_ciu_intx_sum0_cn38xx cn38xxp2;
+ struct cvmx_ciu_intx_sum0_cn30xx cn50xx;
+ struct cvmx_ciu_intx_sum0_cn52xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn52xx;
+ struct cvmx_ciu_intx_sum0_cn52xx cn52xxp1;
+ struct cvmx_ciu_intx_sum0_cn56xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn56xx;
+ struct cvmx_ciu_intx_sum0_cn56xx cn56xxp1;
+ struct cvmx_ciu_intx_sum0_cn38xx cn58xx;
+ struct cvmx_ciu_intx_sum0_cn38xx cn58xxp1;
+};
+
+union cvmx_ciu_intx_sum4 {
+ uint64_t u64;
+ struct cvmx_ciu_intx_sum4_s {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } s;
+ struct cvmx_ciu_intx_sum4_cn50xx {
+ uint64_t reserved_59_63:5;
+ uint64_t mpi:1;
+ uint64_t pcm:1;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t reserved_47_47:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn50xx;
+ struct cvmx_ciu_intx_sum4_cn52xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t reserved_51_51:1;
+ uint64_t ipd_drp:1;
+ uint64_t reserved_49_49:1;
+ uint64_t gmx_drp:1;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn52xx;
+ struct cvmx_ciu_intx_sum4_cn52xx cn52xxp1;
+ struct cvmx_ciu_intx_sum4_cn56xx {
+ uint64_t bootdma:1;
+ uint64_t mii:1;
+ uint64_t ipdppthr:1;
+ uint64_t powiq:1;
+ uint64_t twsi2:1;
+ uint64_t reserved_57_58:2;
+ uint64_t usb:1;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn56xx;
+ struct cvmx_ciu_intx_sum4_cn56xx cn56xxp1;
+ struct cvmx_ciu_intx_sum4_cn58xx {
+ uint64_t reserved_56_63:8;
+ uint64_t timer:4;
+ uint64_t key_zero:1;
+ uint64_t ipd_drp:1;
+ uint64_t gmx_drp:2;
+ uint64_t trace:1;
+ uint64_t rml:1;
+ uint64_t twsi:1;
+ uint64_t wdog_sum:1;
+ uint64_t pci_msi:4;
+ uint64_t pci_int:4;
+ uint64_t uart:2;
+ uint64_t mbox:2;
+ uint64_t gpio:16;
+ uint64_t workq:16;
+ } cn58xx;
+ struct cvmx_ciu_intx_sum4_cn58xx cn58xxp1;
+};
+
+union cvmx_ciu_int_sum1 {
+ uint64_t u64;
+ struct cvmx_ciu_int_sum1_s {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t wdog:16;
+ } s;
+ struct cvmx_ciu_int_sum1_cn30xx {
+ uint64_t reserved_1_63:63;
+ uint64_t wdog:1;
+ } cn30xx;
+ struct cvmx_ciu_int_sum1_cn31xx {
+ uint64_t reserved_2_63:62;
+ uint64_t wdog:2;
+ } cn31xx;
+ struct cvmx_ciu_int_sum1_cn38xx {
+ uint64_t reserved_16_63:48;
+ uint64_t wdog:16;
+ } cn38xx;
+ struct cvmx_ciu_int_sum1_cn38xx cn38xxp2;
+ struct cvmx_ciu_int_sum1_cn31xx cn50xx;
+ struct cvmx_ciu_int_sum1_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t nand:1;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xx;
+ struct cvmx_ciu_int_sum1_cn52xxp1 {
+ uint64_t reserved_19_63:45;
+ uint64_t mii1:1;
+ uint64_t usb1:1;
+ uint64_t uart2:1;
+ uint64_t reserved_4_15:12;
+ uint64_t wdog:4;
+ } cn52xxp1;
+ struct cvmx_ciu_int_sum1_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t wdog:12;
+ } cn56xx;
+ struct cvmx_ciu_int_sum1_cn56xx cn56xxp1;
+ struct cvmx_ciu_int_sum1_cn38xx cn58xx;
+ struct cvmx_ciu_int_sum1_cn38xx cn58xxp1;
+};
+
+union cvmx_ciu_mbox_clrx {
+ uint64_t u64;
+ struct cvmx_ciu_mbox_clrx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t bits:32;
+ } s;
+ struct cvmx_ciu_mbox_clrx_s cn30xx;
+ struct cvmx_ciu_mbox_clrx_s cn31xx;
+ struct cvmx_ciu_mbox_clrx_s cn38xx;
+ struct cvmx_ciu_mbox_clrx_s cn38xxp2;
+ struct cvmx_ciu_mbox_clrx_s cn50xx;
+ struct cvmx_ciu_mbox_clrx_s cn52xx;
+ struct cvmx_ciu_mbox_clrx_s cn52xxp1;
+ struct cvmx_ciu_mbox_clrx_s cn56xx;
+ struct cvmx_ciu_mbox_clrx_s cn56xxp1;
+ struct cvmx_ciu_mbox_clrx_s cn58xx;
+ struct cvmx_ciu_mbox_clrx_s cn58xxp1;
+};
+
+union cvmx_ciu_mbox_setx {
+ uint64_t u64;
+ struct cvmx_ciu_mbox_setx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t bits:32;
+ } s;
+ struct cvmx_ciu_mbox_setx_s cn30xx;
+ struct cvmx_ciu_mbox_setx_s cn31xx;
+ struct cvmx_ciu_mbox_setx_s cn38xx;
+ struct cvmx_ciu_mbox_setx_s cn38xxp2;
+ struct cvmx_ciu_mbox_setx_s cn50xx;
+ struct cvmx_ciu_mbox_setx_s cn52xx;
+ struct cvmx_ciu_mbox_setx_s cn52xxp1;
+ struct cvmx_ciu_mbox_setx_s cn56xx;
+ struct cvmx_ciu_mbox_setx_s cn56xxp1;
+ struct cvmx_ciu_mbox_setx_s cn58xx;
+ struct cvmx_ciu_mbox_setx_s cn58xxp1;
+};
+
+union cvmx_ciu_nmi {
+ uint64_t u64;
+ struct cvmx_ciu_nmi_s {
+ uint64_t reserved_16_63:48;
+ uint64_t nmi:16;
+ } s;
+ struct cvmx_ciu_nmi_cn30xx {
+ uint64_t reserved_1_63:63;
+ uint64_t nmi:1;
+ } cn30xx;
+ struct cvmx_ciu_nmi_cn31xx {
+ uint64_t reserved_2_63:62;
+ uint64_t nmi:2;
+ } cn31xx;
+ struct cvmx_ciu_nmi_s cn38xx;
+ struct cvmx_ciu_nmi_s cn38xxp2;
+ struct cvmx_ciu_nmi_cn31xx cn50xx;
+ struct cvmx_ciu_nmi_cn52xx {
+ uint64_t reserved_4_63:60;
+ uint64_t nmi:4;
+ } cn52xx;
+ struct cvmx_ciu_nmi_cn52xx cn52xxp1;
+ struct cvmx_ciu_nmi_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t nmi:12;
+ } cn56xx;
+ struct cvmx_ciu_nmi_cn56xx cn56xxp1;
+ struct cvmx_ciu_nmi_s cn58xx;
+ struct cvmx_ciu_nmi_s cn58xxp1;
+};
+
+union cvmx_ciu_pci_inta {
+ uint64_t u64;
+ struct cvmx_ciu_pci_inta_s {
+ uint64_t reserved_2_63:62;
+ uint64_t intr:2;
+ } s;
+ struct cvmx_ciu_pci_inta_s cn30xx;
+ struct cvmx_ciu_pci_inta_s cn31xx;
+ struct cvmx_ciu_pci_inta_s cn38xx;
+ struct cvmx_ciu_pci_inta_s cn38xxp2;
+ struct cvmx_ciu_pci_inta_s cn50xx;
+ struct cvmx_ciu_pci_inta_s cn52xx;
+ struct cvmx_ciu_pci_inta_s cn52xxp1;
+ struct cvmx_ciu_pci_inta_s cn56xx;
+ struct cvmx_ciu_pci_inta_s cn56xxp1;
+ struct cvmx_ciu_pci_inta_s cn58xx;
+ struct cvmx_ciu_pci_inta_s cn58xxp1;
+};
+
+union cvmx_ciu_pp_dbg {
+ uint64_t u64;
+ struct cvmx_ciu_pp_dbg_s {
+ uint64_t reserved_16_63:48;
+ uint64_t ppdbg:16;
+ } s;
+ struct cvmx_ciu_pp_dbg_cn30xx {
+ uint64_t reserved_1_63:63;
+ uint64_t ppdbg:1;
+ } cn30xx;
+ struct cvmx_ciu_pp_dbg_cn31xx {
+ uint64_t reserved_2_63:62;
+ uint64_t ppdbg:2;
+ } cn31xx;
+ struct cvmx_ciu_pp_dbg_s cn38xx;
+ struct cvmx_ciu_pp_dbg_s cn38xxp2;
+ struct cvmx_ciu_pp_dbg_cn31xx cn50xx;
+ struct cvmx_ciu_pp_dbg_cn52xx {
+ uint64_t reserved_4_63:60;
+ uint64_t ppdbg:4;
+ } cn52xx;
+ struct cvmx_ciu_pp_dbg_cn52xx cn52xxp1;
+ struct cvmx_ciu_pp_dbg_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t ppdbg:12;
+ } cn56xx;
+ struct cvmx_ciu_pp_dbg_cn56xx cn56xxp1;
+ struct cvmx_ciu_pp_dbg_s cn58xx;
+ struct cvmx_ciu_pp_dbg_s cn58xxp1;
+};
+
+union cvmx_ciu_pp_pokex {
+ uint64_t u64;
+ struct cvmx_ciu_pp_pokex_s {
+ uint64_t reserved_0_63:64;
+ } s;
+ struct cvmx_ciu_pp_pokex_s cn30xx;
+ struct cvmx_ciu_pp_pokex_s cn31xx;
+ struct cvmx_ciu_pp_pokex_s cn38xx;
+ struct cvmx_ciu_pp_pokex_s cn38xxp2;
+ struct cvmx_ciu_pp_pokex_s cn50xx;
+ struct cvmx_ciu_pp_pokex_s cn52xx;
+ struct cvmx_ciu_pp_pokex_s cn52xxp1;
+ struct cvmx_ciu_pp_pokex_s cn56xx;
+ struct cvmx_ciu_pp_pokex_s cn56xxp1;
+ struct cvmx_ciu_pp_pokex_s cn58xx;
+ struct cvmx_ciu_pp_pokex_s cn58xxp1;
+};
+
+union cvmx_ciu_pp_rst {
+ uint64_t u64;
+ struct cvmx_ciu_pp_rst_s {
+ uint64_t reserved_16_63:48;
+ uint64_t rst:15;
+ uint64_t rst0:1;
+ } s;
+ struct cvmx_ciu_pp_rst_cn30xx {
+ uint64_t reserved_1_63:63;
+ uint64_t rst0:1;
+ } cn30xx;
+ struct cvmx_ciu_pp_rst_cn31xx {
+ uint64_t reserved_2_63:62;
+ uint64_t rst:1;
+ uint64_t rst0:1;
+ } cn31xx;
+ struct cvmx_ciu_pp_rst_s cn38xx;
+ struct cvmx_ciu_pp_rst_s cn38xxp2;
+ struct cvmx_ciu_pp_rst_cn31xx cn50xx;
+ struct cvmx_ciu_pp_rst_cn52xx {
+ uint64_t reserved_4_63:60;
+ uint64_t rst:3;
+ uint64_t rst0:1;
+ } cn52xx;
+ struct cvmx_ciu_pp_rst_cn52xx cn52xxp1;
+ struct cvmx_ciu_pp_rst_cn56xx {
+ uint64_t reserved_12_63:52;
+ uint64_t rst:11;
+ uint64_t rst0:1;
+ } cn56xx;
+ struct cvmx_ciu_pp_rst_cn56xx cn56xxp1;
+ struct cvmx_ciu_pp_rst_s cn58xx;
+ struct cvmx_ciu_pp_rst_s cn58xxp1;
+};
+
+union cvmx_ciu_qlm_dcok {
+ uint64_t u64;
+ struct cvmx_ciu_qlm_dcok_s {
+ uint64_t reserved_4_63:60;
+ uint64_t qlm_dcok:4;
+ } s;
+ struct cvmx_ciu_qlm_dcok_cn52xx {
+ uint64_t reserved_2_63:62;
+ uint64_t qlm_dcok:2;
+ } cn52xx;
+ struct cvmx_ciu_qlm_dcok_cn52xx cn52xxp1;
+ struct cvmx_ciu_qlm_dcok_s cn56xx;
+ struct cvmx_ciu_qlm_dcok_s cn56xxp1;
+};
+
+union cvmx_ciu_qlm_jtgc {
+ uint64_t u64;
+ struct cvmx_ciu_qlm_jtgc_s {
+ uint64_t reserved_11_63:53;
+ uint64_t clk_div:3;
+ uint64_t reserved_6_7:2;
+ uint64_t mux_sel:2;
+ uint64_t bypass:4;
+ } s;
+ struct cvmx_ciu_qlm_jtgc_cn52xx {
+ uint64_t reserved_11_63:53;
+ uint64_t clk_div:3;
+ uint64_t reserved_5_7:3;
+ uint64_t mux_sel:1;
+ uint64_t reserved_2_3:2;
+ uint64_t bypass:2;
+ } cn52xx;
+ struct cvmx_ciu_qlm_jtgc_cn52xx cn52xxp1;
+ struct cvmx_ciu_qlm_jtgc_s cn56xx;
+ struct cvmx_ciu_qlm_jtgc_s cn56xxp1;
+};
+
+union cvmx_ciu_qlm_jtgd {
+ uint64_t u64;
+ struct cvmx_ciu_qlm_jtgd_s {
+ uint64_t capture:1;
+ uint64_t shift:1;
+ uint64_t update:1;
+ uint64_t reserved_44_60:17;
+ uint64_t select:4;
+ uint64_t reserved_37_39:3;
+ uint64_t shft_cnt:5;
+ uint64_t shft_reg:32;
+ } s;
+ struct cvmx_ciu_qlm_jtgd_cn52xx {
+ uint64_t capture:1;
+ uint64_t shift:1;
+ uint64_t update:1;
+ uint64_t reserved_42_60:19;
+ uint64_t select:2;
+ uint64_t reserved_37_39:3;
+ uint64_t shft_cnt:5;
+ uint64_t shft_reg:32;
+ } cn52xx;
+ struct cvmx_ciu_qlm_jtgd_cn52xx cn52xxp1;
+ struct cvmx_ciu_qlm_jtgd_s cn56xx;
+ struct cvmx_ciu_qlm_jtgd_cn56xxp1 {
+ uint64_t capture:1;
+ uint64_t shift:1;
+ uint64_t update:1;
+ uint64_t reserved_37_60:24;
+ uint64_t shft_cnt:5;
+ uint64_t shft_reg:32;
+ } cn56xxp1;
+};
+
+union cvmx_ciu_soft_bist {
+ uint64_t u64;
+ struct cvmx_ciu_soft_bist_s {
+ uint64_t reserved_1_63:63;
+ uint64_t soft_bist:1;
+ } s;
+ struct cvmx_ciu_soft_bist_s cn30xx;
+ struct cvmx_ciu_soft_bist_s cn31xx;
+ struct cvmx_ciu_soft_bist_s cn38xx;
+ struct cvmx_ciu_soft_bist_s cn38xxp2;
+ struct cvmx_ciu_soft_bist_s cn50xx;
+ struct cvmx_ciu_soft_bist_s cn52xx;
+ struct cvmx_ciu_soft_bist_s cn52xxp1;
+ struct cvmx_ciu_soft_bist_s cn56xx;
+ struct cvmx_ciu_soft_bist_s cn56xxp1;
+ struct cvmx_ciu_soft_bist_s cn58xx;
+ struct cvmx_ciu_soft_bist_s cn58xxp1;
+};
+
+union cvmx_ciu_soft_prst {
+ uint64_t u64;
+ struct cvmx_ciu_soft_prst_s {
+ uint64_t reserved_3_63:61;
+ uint64_t host64:1;
+ uint64_t npi:1;
+ uint64_t soft_prst:1;
+ } s;
+ struct cvmx_ciu_soft_prst_s cn30xx;
+ struct cvmx_ciu_soft_prst_s cn31xx;
+ struct cvmx_ciu_soft_prst_s cn38xx;
+ struct cvmx_ciu_soft_prst_s cn38xxp2;
+ struct cvmx_ciu_soft_prst_s cn50xx;
+ struct cvmx_ciu_soft_prst_cn52xx {
+ uint64_t reserved_1_63:63;
+ uint64_t soft_prst:1;
+ } cn52xx;
+ struct cvmx_ciu_soft_prst_cn52xx cn52xxp1;
+ struct cvmx_ciu_soft_prst_cn52xx cn56xx;
+ struct cvmx_ciu_soft_prst_cn52xx cn56xxp1;
+ struct cvmx_ciu_soft_prst_s cn58xx;
+ struct cvmx_ciu_soft_prst_s cn58xxp1;
+};
+
+union cvmx_ciu_soft_prst1 {
+ uint64_t u64;
+ struct cvmx_ciu_soft_prst1_s {
+ uint64_t reserved_1_63:63;
+ uint64_t soft_prst:1;
+ } s;
+ struct cvmx_ciu_soft_prst1_s cn52xx;
+ struct cvmx_ciu_soft_prst1_s cn52xxp1;
+ struct cvmx_ciu_soft_prst1_s cn56xx;
+ struct cvmx_ciu_soft_prst1_s cn56xxp1;
+};
+
+union cvmx_ciu_soft_rst {
+ uint64_t u64;
+ struct cvmx_ciu_soft_rst_s {
+ uint64_t reserved_1_63:63;
+ uint64_t soft_rst:1;
+ } s;
+ struct cvmx_ciu_soft_rst_s cn30xx;
+ struct cvmx_ciu_soft_rst_s cn31xx;
+ struct cvmx_ciu_soft_rst_s cn38xx;
+ struct cvmx_ciu_soft_rst_s cn38xxp2;
+ struct cvmx_ciu_soft_rst_s cn50xx;
+ struct cvmx_ciu_soft_rst_s cn52xx;
+ struct cvmx_ciu_soft_rst_s cn52xxp1;
+ struct cvmx_ciu_soft_rst_s cn56xx;
+ struct cvmx_ciu_soft_rst_s cn56xxp1;
+ struct cvmx_ciu_soft_rst_s cn58xx;
+ struct cvmx_ciu_soft_rst_s cn58xxp1;
+};
+
+union cvmx_ciu_timx {
+ uint64_t u64;
+ struct cvmx_ciu_timx_s {
+ uint64_t reserved_37_63:27;
+ uint64_t one_shot:1;
+ uint64_t len:36;
+ } s;
+ struct cvmx_ciu_timx_s cn30xx;
+ struct cvmx_ciu_timx_s cn31xx;
+ struct cvmx_ciu_timx_s cn38xx;
+ struct cvmx_ciu_timx_s cn38xxp2;
+ struct cvmx_ciu_timx_s cn50xx;
+ struct cvmx_ciu_timx_s cn52xx;
+ struct cvmx_ciu_timx_s cn52xxp1;
+ struct cvmx_ciu_timx_s cn56xx;
+ struct cvmx_ciu_timx_s cn56xxp1;
+ struct cvmx_ciu_timx_s cn58xx;
+ struct cvmx_ciu_timx_s cn58xxp1;
+};
+
+union cvmx_ciu_wdogx {
+ uint64_t u64;
+ struct cvmx_ciu_wdogx_s {
+ uint64_t reserved_46_63:18;
+ uint64_t gstopen:1;
+ uint64_t dstop:1;
+ uint64_t cnt:24;
+ uint64_t len:16;
+ uint64_t state:2;
+ uint64_t mode:2;
+ } s;
+ struct cvmx_ciu_wdogx_s cn30xx;
+ struct cvmx_ciu_wdogx_s cn31xx;
+ struct cvmx_ciu_wdogx_s cn38xx;
+ struct cvmx_ciu_wdogx_s cn38xxp2;
+ struct cvmx_ciu_wdogx_s cn50xx;
+ struct cvmx_ciu_wdogx_s cn52xx;
+ struct cvmx_ciu_wdogx_s cn52xxp1;
+ struct cvmx_ciu_wdogx_s cn56xx;
+ struct cvmx_ciu_wdogx_s cn56xxp1;
+ struct cvmx_ciu_wdogx_s cn58xx;
+ struct cvmx_ciu_wdogx_s cn58xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-gpio-defs.h b/arch/mips/include/asm/octeon/cvmx-gpio-defs.h
new file mode 100644
index 0000000..5fdd6ba
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-gpio-defs.h
@@ -0,0 +1,219 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_GPIO_DEFS_H__
+#define __CVMX_GPIO_DEFS_H__
+
+#define CVMX_GPIO_BIT_CFGX(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000000800ull + (((offset) & 15) * 8))
+#define CVMX_GPIO_BOOT_ENA \
+ CVMX_ADD_IO_SEG(0x00010700000008A8ull)
+#define CVMX_GPIO_CLK_GENX(offset) \
+ CVMX_ADD_IO_SEG(0x00010700000008C0ull + (((offset) & 3) * 8))
+#define CVMX_GPIO_DBG_ENA \
+ CVMX_ADD_IO_SEG(0x00010700000008A0ull)
+#define CVMX_GPIO_INT_CLR \
+ CVMX_ADD_IO_SEG(0x0001070000000898ull)
+#define CVMX_GPIO_RX_DAT \
+ CVMX_ADD_IO_SEG(0x0001070000000880ull)
+#define CVMX_GPIO_TX_CLR \
+ CVMX_ADD_IO_SEG(0x0001070000000890ull)
+#define CVMX_GPIO_TX_SET \
+ CVMX_ADD_IO_SEG(0x0001070000000888ull)
+#define CVMX_GPIO_XBIT_CFGX(offset) \
+ CVMX_ADD_IO_SEG(0x0001070000000900ull + (((offset) & 31) * 8) - 8 * 16)
+
+union cvmx_gpio_bit_cfgx {
+ uint64_t u64;
+ struct cvmx_gpio_bit_cfgx_s {
+ uint64_t reserved_15_63:49;
+ uint64_t clk_gen:1;
+ uint64_t clk_sel:2;
+ uint64_t fil_sel:4;
+ uint64_t fil_cnt:4;
+ uint64_t int_type:1;
+ uint64_t int_en:1;
+ uint64_t rx_xor:1;
+ uint64_t tx_oe:1;
+ } s;
+ struct cvmx_gpio_bit_cfgx_cn30xx {
+ uint64_t reserved_12_63:52;
+ uint64_t fil_sel:4;
+ uint64_t fil_cnt:4;
+ uint64_t int_type:1;
+ uint64_t int_en:1;
+ uint64_t rx_xor:1;
+ uint64_t tx_oe:1;
+ } cn30xx;
+ struct cvmx_gpio_bit_cfgx_cn30xx cn31xx;
+ struct cvmx_gpio_bit_cfgx_cn30xx cn38xx;
+ struct cvmx_gpio_bit_cfgx_cn30xx cn38xxp2;
+ struct cvmx_gpio_bit_cfgx_cn30xx cn50xx;
+ struct cvmx_gpio_bit_cfgx_s cn52xx;
+ struct cvmx_gpio_bit_cfgx_s cn52xxp1;
+ struct cvmx_gpio_bit_cfgx_s cn56xx;
+ struct cvmx_gpio_bit_cfgx_s cn56xxp1;
+ struct cvmx_gpio_bit_cfgx_cn30xx cn58xx;
+ struct cvmx_gpio_bit_cfgx_cn30xx cn58xxp1;
+};
+
+union cvmx_gpio_boot_ena {
+ uint64_t u64;
+ struct cvmx_gpio_boot_ena_s {
+ uint64_t reserved_12_63:52;
+ uint64_t boot_ena:4;
+ uint64_t reserved_0_7:8;
+ } s;
+ struct cvmx_gpio_boot_ena_s cn30xx;
+ struct cvmx_gpio_boot_ena_s cn31xx;
+ struct cvmx_gpio_boot_ena_s cn50xx;
+};
+
+union cvmx_gpio_clk_genx {
+ uint64_t u64;
+ struct cvmx_gpio_clk_genx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t n:32;
+ } s;
+ struct cvmx_gpio_clk_genx_s cn52xx;
+ struct cvmx_gpio_clk_genx_s cn52xxp1;
+ struct cvmx_gpio_clk_genx_s cn56xx;
+ struct cvmx_gpio_clk_genx_s cn56xxp1;
+};
+
+union cvmx_gpio_dbg_ena {
+ uint64_t u64;
+ struct cvmx_gpio_dbg_ena_s {
+ uint64_t reserved_21_63:43;
+ uint64_t dbg_ena:21;
+ } s;
+ struct cvmx_gpio_dbg_ena_s cn30xx;
+ struct cvmx_gpio_dbg_ena_s cn31xx;
+ struct cvmx_gpio_dbg_ena_s cn50xx;
+};
+
+union cvmx_gpio_int_clr {
+ uint64_t u64;
+ struct cvmx_gpio_int_clr_s {
+ uint64_t reserved_16_63:48;
+ uint64_t type:16;
+ } s;
+ struct cvmx_gpio_int_clr_s cn30xx;
+ struct cvmx_gpio_int_clr_s cn31xx;
+ struct cvmx_gpio_int_clr_s cn38xx;
+ struct cvmx_gpio_int_clr_s cn38xxp2;
+ struct cvmx_gpio_int_clr_s cn50xx;
+ struct cvmx_gpio_int_clr_s cn52xx;
+ struct cvmx_gpio_int_clr_s cn52xxp1;
+ struct cvmx_gpio_int_clr_s cn56xx;
+ struct cvmx_gpio_int_clr_s cn56xxp1;
+ struct cvmx_gpio_int_clr_s cn58xx;
+ struct cvmx_gpio_int_clr_s cn58xxp1;
+};
+
+union cvmx_gpio_rx_dat {
+ uint64_t u64;
+ struct cvmx_gpio_rx_dat_s {
+ uint64_t reserved_24_63:40;
+ uint64_t dat:24;
+ } s;
+ struct cvmx_gpio_rx_dat_s cn30xx;
+ struct cvmx_gpio_rx_dat_s cn31xx;
+ struct cvmx_gpio_rx_dat_cn38xx {
+ uint64_t reserved_16_63:48;
+ uint64_t dat:16;
+ } cn38xx;
+ struct cvmx_gpio_rx_dat_cn38xx cn38xxp2;
+ struct cvmx_gpio_rx_dat_s cn50xx;
+ struct cvmx_gpio_rx_dat_cn38xx cn52xx;
+ struct cvmx_gpio_rx_dat_cn38xx cn52xxp1;
+ struct cvmx_gpio_rx_dat_cn38xx cn56xx;
+ struct cvmx_gpio_rx_dat_cn38xx cn56xxp1;
+ struct cvmx_gpio_rx_dat_cn38xx cn58xx;
+ struct cvmx_gpio_rx_dat_cn38xx cn58xxp1;
+};
+
+union cvmx_gpio_tx_clr {
+ uint64_t u64;
+ struct cvmx_gpio_tx_clr_s {
+ uint64_t reserved_24_63:40;
+ uint64_t clr:24;
+ } s;
+ struct cvmx_gpio_tx_clr_s cn30xx;
+ struct cvmx_gpio_tx_clr_s cn31xx;
+ struct cvmx_gpio_tx_clr_cn38xx {
+ uint64_t reserved_16_63:48;
+ uint64_t clr:16;
+ } cn38xx;
+ struct cvmx_gpio_tx_clr_cn38xx cn38xxp2;
+ struct cvmx_gpio_tx_clr_s cn50xx;
+ struct cvmx_gpio_tx_clr_cn38xx cn52xx;
+ struct cvmx_gpio_tx_clr_cn38xx cn52xxp1;
+ struct cvmx_gpio_tx_clr_cn38xx cn56xx;
+ struct cvmx_gpio_tx_clr_cn38xx cn56xxp1;
+ struct cvmx_gpio_tx_clr_cn38xx cn58xx;
+ struct cvmx_gpio_tx_clr_cn38xx cn58xxp1;
+};
+
+union cvmx_gpio_tx_set {
+ uint64_t u64;
+ struct cvmx_gpio_tx_set_s {
+ uint64_t reserved_24_63:40;
+ uint64_t set:24;
+ } s;
+ struct cvmx_gpio_tx_set_s cn30xx;
+ struct cvmx_gpio_tx_set_s cn31xx;
+ struct cvmx_gpio_tx_set_cn38xx {
+ uint64_t reserved_16_63:48;
+ uint64_t set:16;
+ } cn38xx;
+ struct cvmx_gpio_tx_set_cn38xx cn38xxp2;
+ struct cvmx_gpio_tx_set_s cn50xx;
+ struct cvmx_gpio_tx_set_cn38xx cn52xx;
+ struct cvmx_gpio_tx_set_cn38xx cn52xxp1;
+ struct cvmx_gpio_tx_set_cn38xx cn56xx;
+ struct cvmx_gpio_tx_set_cn38xx cn56xxp1;
+ struct cvmx_gpio_tx_set_cn38xx cn58xx;
+ struct cvmx_gpio_tx_set_cn38xx cn58xxp1;
+};
+
+union cvmx_gpio_xbit_cfgx {
+ uint64_t u64;
+ struct cvmx_gpio_xbit_cfgx_s {
+ uint64_t reserved_12_63:52;
+ uint64_t fil_sel:4;
+ uint64_t fil_cnt:4;
+ uint64_t reserved_2_3:2;
+ uint64_t rx_xor:1;
+ uint64_t tx_oe:1;
+ } s;
+ struct cvmx_gpio_xbit_cfgx_s cn30xx;
+ struct cvmx_gpio_xbit_cfgx_s cn31xx;
+ struct cvmx_gpio_xbit_cfgx_s cn50xx;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-iob-defs.h b/arch/mips/include/asm/octeon/cvmx-iob-defs.h
new file mode 100644
index 0000000..0ee36ba
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-iob-defs.h
@@ -0,0 +1,530 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_IOB_DEFS_H__
+#define __CVMX_IOB_DEFS_H__
+
+#define CVMX_IOB_BIST_STATUS \
+ CVMX_ADD_IO_SEG(0x00011800F00007F8ull)
+#define CVMX_IOB_CTL_STATUS \
+ CVMX_ADD_IO_SEG(0x00011800F0000050ull)
+#define CVMX_IOB_DWB_PRI_CNT \
+ CVMX_ADD_IO_SEG(0x00011800F0000028ull)
+#define CVMX_IOB_FAU_TIMEOUT \
+ CVMX_ADD_IO_SEG(0x00011800F0000000ull)
+#define CVMX_IOB_I2C_PRI_CNT \
+ CVMX_ADD_IO_SEG(0x00011800F0000010ull)
+#define CVMX_IOB_INB_CONTROL_MATCH \
+ CVMX_ADD_IO_SEG(0x00011800F0000078ull)
+#define CVMX_IOB_INB_CONTROL_MATCH_ENB \
+ CVMX_ADD_IO_SEG(0x00011800F0000088ull)
+#define CVMX_IOB_INB_DATA_MATCH \
+ CVMX_ADD_IO_SEG(0x00011800F0000070ull)
+#define CVMX_IOB_INB_DATA_MATCH_ENB \
+ CVMX_ADD_IO_SEG(0x00011800F0000080ull)
+#define CVMX_IOB_INT_ENB \
+ CVMX_ADD_IO_SEG(0x00011800F0000060ull)
+#define CVMX_IOB_INT_SUM \
+ CVMX_ADD_IO_SEG(0x00011800F0000058ull)
+#define CVMX_IOB_N2C_L2C_PRI_CNT \
+ CVMX_ADD_IO_SEG(0x00011800F0000020ull)
+#define CVMX_IOB_N2C_RSP_PRI_CNT \
+ CVMX_ADD_IO_SEG(0x00011800F0000008ull)
+#define CVMX_IOB_OUTB_COM_PRI_CNT \
+ CVMX_ADD_IO_SEG(0x00011800F0000040ull)
+#define CVMX_IOB_OUTB_CONTROL_MATCH \
+ CVMX_ADD_IO_SEG(0x00011800F0000098ull)
+#define CVMX_IOB_OUTB_CONTROL_MATCH_ENB \
+ CVMX_ADD_IO_SEG(0x00011800F00000A8ull)
+#define CVMX_IOB_OUTB_DATA_MATCH \
+ CVMX_ADD_IO_SEG(0x00011800F0000090ull)
+#define CVMX_IOB_OUTB_DATA_MATCH_ENB \
+ CVMX_ADD_IO_SEG(0x00011800F00000A0ull)
+#define CVMX_IOB_OUTB_FPA_PRI_CNT \
+ CVMX_ADD_IO_SEG(0x00011800F0000048ull)
+#define CVMX_IOB_OUTB_REQ_PRI_CNT \
+ CVMX_ADD_IO_SEG(0x00011800F0000038ull)
+#define CVMX_IOB_P2C_REQ_PRI_CNT \
+ CVMX_ADD_IO_SEG(0x00011800F0000018ull)
+#define CVMX_IOB_PKT_ERR \
+ CVMX_ADD_IO_SEG(0x00011800F0000068ull)
+
+union cvmx_iob_bist_status {
+ uint64_t u64;
+ struct cvmx_iob_bist_status_s {
+ uint64_t reserved_18_63:46;
+ uint64_t icnrcb:1;
+ uint64_t icr0:1;
+ uint64_t icr1:1;
+ uint64_t icnr1:1;
+ uint64_t icnr0:1;
+ uint64_t ibdr0:1;
+ uint64_t ibdr1:1;
+ uint64_t ibr0:1;
+ uint64_t ibr1:1;
+ uint64_t icnrt:1;
+ uint64_t ibrq0:1;
+ uint64_t ibrq1:1;
+ uint64_t icrn0:1;
+ uint64_t icrn1:1;
+ uint64_t icrp0:1;
+ uint64_t icrp1:1;
+ uint64_t ibd:1;
+ uint64_t icd:1;
+ } s;
+ struct cvmx_iob_bist_status_s cn30xx;
+ struct cvmx_iob_bist_status_s cn31xx;
+ struct cvmx_iob_bist_status_s cn38xx;
+ struct cvmx_iob_bist_status_s cn38xxp2;
+ struct cvmx_iob_bist_status_s cn50xx;
+ struct cvmx_iob_bist_status_s cn52xx;
+ struct cvmx_iob_bist_status_s cn52xxp1;
+ struct cvmx_iob_bist_status_s cn56xx;
+ struct cvmx_iob_bist_status_s cn56xxp1;
+ struct cvmx_iob_bist_status_s cn58xx;
+ struct cvmx_iob_bist_status_s cn58xxp1;
+};
+
+union cvmx_iob_ctl_status {
+ uint64_t u64;
+ struct cvmx_iob_ctl_status_s {
+ uint64_t reserved_5_63:59;
+ uint64_t outb_mat:1;
+ uint64_t inb_mat:1;
+ uint64_t pko_enb:1;
+ uint64_t dwb_enb:1;
+ uint64_t fau_end:1;
+ } s;
+ struct cvmx_iob_ctl_status_s cn30xx;
+ struct cvmx_iob_ctl_status_s cn31xx;
+ struct cvmx_iob_ctl_status_s cn38xx;
+ struct cvmx_iob_ctl_status_s cn38xxp2;
+ struct cvmx_iob_ctl_status_s cn50xx;
+ struct cvmx_iob_ctl_status_s cn52xx;
+ struct cvmx_iob_ctl_status_s cn52xxp1;
+ struct cvmx_iob_ctl_status_s cn56xx;
+ struct cvmx_iob_ctl_status_s cn56xxp1;
+ struct cvmx_iob_ctl_status_s cn58xx;
+ struct cvmx_iob_ctl_status_s cn58xxp1;
+};
+
+union cvmx_iob_dwb_pri_cnt {
+ uint64_t u64;
+ struct cvmx_iob_dwb_pri_cnt_s {
+ uint64_t reserved_16_63:48;
+ uint64_t cnt_enb:1;
+ uint64_t cnt_val:15;
+ } s;
+ struct cvmx_iob_dwb_pri_cnt_s cn38xx;
+ struct cvmx_iob_dwb_pri_cnt_s cn38xxp2;
+ struct cvmx_iob_dwb_pri_cnt_s cn52xx;
+ struct cvmx_iob_dwb_pri_cnt_s cn52xxp1;
+ struct cvmx_iob_dwb_pri_cnt_s cn56xx;
+ struct cvmx_iob_dwb_pri_cnt_s cn56xxp1;
+ struct cvmx_iob_dwb_pri_cnt_s cn58xx;
+ struct cvmx_iob_dwb_pri_cnt_s cn58xxp1;
+};
+
+union cvmx_iob_fau_timeout {
+ uint64_t u64;
+ struct cvmx_iob_fau_timeout_s {
+ uint64_t reserved_13_63:51;
+ uint64_t tout_enb:1;
+ uint64_t tout_val:12;
+ } s;
+ struct cvmx_iob_fau_timeout_s cn30xx;
+ struct cvmx_iob_fau_timeout_s cn31xx;
+ struct cvmx_iob_fau_timeout_s cn38xx;
+ struct cvmx_iob_fau_timeout_s cn38xxp2;
+ struct cvmx_iob_fau_timeout_s cn50xx;
+ struct cvmx_iob_fau_timeout_s cn52xx;
+ struct cvmx_iob_fau_timeout_s cn52xxp1;
+ struct cvmx_iob_fau_timeout_s cn56xx;
+ struct cvmx_iob_fau_timeout_s cn56xxp1;
+ struct cvmx_iob_fau_timeout_s cn58xx;
+ struct cvmx_iob_fau_timeout_s cn58xxp1;
+};
+
+union cvmx_iob_i2c_pri_cnt {
+ uint64_t u64;
+ struct cvmx_iob_i2c_pri_cnt_s {
+ uint64_t reserved_16_63:48;
+ uint64_t cnt_enb:1;
+ uint64_t cnt_val:15;
+ } s;
+ struct cvmx_iob_i2c_pri_cnt_s cn38xx;
+ struct cvmx_iob_i2c_pri_cnt_s cn38xxp2;
+ struct cvmx_iob_i2c_pri_cnt_s cn52xx;
+ struct cvmx_iob_i2c_pri_cnt_s cn52xxp1;
+ struct cvmx_iob_i2c_pri_cnt_s cn56xx;
+ struct cvmx_iob_i2c_pri_cnt_s cn56xxp1;
+ struct cvmx_iob_i2c_pri_cnt_s cn58xx;
+ struct cvmx_iob_i2c_pri_cnt_s cn58xxp1;
+};
+
+union cvmx_iob_inb_control_match {
+ uint64_t u64;
+ struct cvmx_iob_inb_control_match_s {
+ uint64_t reserved_29_63:35;
+ uint64_t mask:8;
+ uint64_t opc:4;
+ uint64_t dst:9;
+ uint64_t src:8;
+ } s;
+ struct cvmx_iob_inb_control_match_s cn30xx;
+ struct cvmx_iob_inb_control_match_s cn31xx;
+ struct cvmx_iob_inb_control_match_s cn38xx;
+ struct cvmx_iob_inb_control_match_s cn38xxp2;
+ struct cvmx_iob_inb_control_match_s cn50xx;
+ struct cvmx_iob_inb_control_match_s cn52xx;
+ struct cvmx_iob_inb_control_match_s cn52xxp1;
+ struct cvmx_iob_inb_control_match_s cn56xx;
+ struct cvmx_iob_inb_control_match_s cn56xxp1;
+ struct cvmx_iob_inb_control_match_s cn58xx;
+ struct cvmx_iob_inb_control_match_s cn58xxp1;
+};
+
+union cvmx_iob_inb_control_match_enb {
+ uint64_t u64;
+ struct cvmx_iob_inb_control_match_enb_s {
+ uint64_t reserved_29_63:35;
+ uint64_t mask:8;
+ uint64_t opc:4;
+ uint64_t dst:9;
+ uint64_t src:8;
+ } s;
+ struct cvmx_iob_inb_control_match_enb_s cn30xx;
+ struct cvmx_iob_inb_control_match_enb_s cn31xx;
+ struct cvmx_iob_inb_control_match_enb_s cn38xx;
+ struct cvmx_iob_inb_control_match_enb_s cn38xxp2;
+ struct cvmx_iob_inb_control_match_enb_s cn50xx;
+ struct cvmx_iob_inb_control_match_enb_s cn52xx;
+ struct cvmx_iob_inb_control_match_enb_s cn52xxp1;
+ struct cvmx_iob_inb_control_match_enb_s cn56xx;
+ struct cvmx_iob_inb_control_match_enb_s cn56xxp1;
+ struct cvmx_iob_inb_control_match_enb_s cn58xx;
+ struct cvmx_iob_inb_control_match_enb_s cn58xxp1;
+};
+
+union cvmx_iob_inb_data_match {
+ uint64_t u64;
+ struct cvmx_iob_inb_data_match_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_iob_inb_data_match_s cn30xx;
+ struct cvmx_iob_inb_data_match_s cn31xx;
+ struct cvmx_iob_inb_data_match_s cn38xx;
+ struct cvmx_iob_inb_data_match_s cn38xxp2;
+ struct cvmx_iob_inb_data_match_s cn50xx;
+ struct cvmx_iob_inb_data_match_s cn52xx;
+ struct cvmx_iob_inb_data_match_s cn52xxp1;
+ struct cvmx_iob_inb_data_match_s cn56xx;
+ struct cvmx_iob_inb_data_match_s cn56xxp1;
+ struct cvmx_iob_inb_data_match_s cn58xx;
+ struct cvmx_iob_inb_data_match_s cn58xxp1;
+};
+
+union cvmx_iob_inb_data_match_enb {
+ uint64_t u64;
+ struct cvmx_iob_inb_data_match_enb_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_iob_inb_data_match_enb_s cn30xx;
+ struct cvmx_iob_inb_data_match_enb_s cn31xx;
+ struct cvmx_iob_inb_data_match_enb_s cn38xx;
+ struct cvmx_iob_inb_data_match_enb_s cn38xxp2;
+ struct cvmx_iob_inb_data_match_enb_s cn50xx;
+ struct cvmx_iob_inb_data_match_enb_s cn52xx;
+ struct cvmx_iob_inb_data_match_enb_s cn52xxp1;
+ struct cvmx_iob_inb_data_match_enb_s cn56xx;
+ struct cvmx_iob_inb_data_match_enb_s cn56xxp1;
+ struct cvmx_iob_inb_data_match_enb_s cn58xx;
+ struct cvmx_iob_inb_data_match_enb_s cn58xxp1;
+};
+
+union cvmx_iob_int_enb {
+ uint64_t u64;
+ struct cvmx_iob_int_enb_s {
+ uint64_t reserved_6_63:58;
+ uint64_t p_dat:1;
+ uint64_t np_dat:1;
+ uint64_t p_eop:1;
+ uint64_t p_sop:1;
+ uint64_t np_eop:1;
+ uint64_t np_sop:1;
+ } s;
+ struct cvmx_iob_int_enb_cn30xx {
+ uint64_t reserved_4_63:60;
+ uint64_t p_eop:1;
+ uint64_t p_sop:1;
+ uint64_t np_eop:1;
+ uint64_t np_sop:1;
+ } cn30xx;
+ struct cvmx_iob_int_enb_cn30xx cn31xx;
+ struct cvmx_iob_int_enb_cn30xx cn38xx;
+ struct cvmx_iob_int_enb_cn30xx cn38xxp2;
+ struct cvmx_iob_int_enb_s cn50xx;
+ struct cvmx_iob_int_enb_s cn52xx;
+ struct cvmx_iob_int_enb_s cn52xxp1;
+ struct cvmx_iob_int_enb_s cn56xx;
+ struct cvmx_iob_int_enb_s cn56xxp1;
+ struct cvmx_iob_int_enb_s cn58xx;
+ struct cvmx_iob_int_enb_s cn58xxp1;
+};
+
+union cvmx_iob_int_sum {
+ uint64_t u64;
+ struct cvmx_iob_int_sum_s {
+ uint64_t reserved_6_63:58;
+ uint64_t p_dat:1;
+ uint64_t np_dat:1;
+ uint64_t p_eop:1;
+ uint64_t p_sop:1;
+ uint64_t np_eop:1;
+ uint64_t np_sop:1;
+ } s;
+ struct cvmx_iob_int_sum_cn30xx {
+ uint64_t reserved_4_63:60;
+ uint64_t p_eop:1;
+ uint64_t p_sop:1;
+ uint64_t np_eop:1;
+ uint64_t np_sop:1;
+ } cn30xx;
+ struct cvmx_iob_int_sum_cn30xx cn31xx;
+ struct cvmx_iob_int_sum_cn30xx cn38xx;
+ struct cvmx_iob_int_sum_cn30xx cn38xxp2;
+ struct cvmx_iob_int_sum_s cn50xx;
+ struct cvmx_iob_int_sum_s cn52xx;
+ struct cvmx_iob_int_sum_s cn52xxp1;
+ struct cvmx_iob_int_sum_s cn56xx;
+ struct cvmx_iob_int_sum_s cn56xxp1;
+ struct cvmx_iob_int_sum_s cn58xx;
+ struct cvmx_iob_int_sum_s cn58xxp1;
+};
+
+union cvmx_iob_n2c_l2c_pri_cnt {
+ uint64_t u64;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s {
+ uint64_t reserved_16_63:48;
+ uint64_t cnt_enb:1;
+ uint64_t cnt_val:15;
+ } s;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn38xx;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn38xxp2;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn52xx;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn52xxp1;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn56xx;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn56xxp1;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn58xx;
+ struct cvmx_iob_n2c_l2c_pri_cnt_s cn58xxp1;
+};
+
+union cvmx_iob_n2c_rsp_pri_cnt {
+ uint64_t u64;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s {
+ uint64_t reserved_16_63:48;
+ uint64_t cnt_enb:1;
+ uint64_t cnt_val:15;
+ } s;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn38xx;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn38xxp2;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn52xx;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn52xxp1;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn56xx;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn56xxp1;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn58xx;
+ struct cvmx_iob_n2c_rsp_pri_cnt_s cn58xxp1;
+};
+
+union cvmx_iob_outb_com_pri_cnt {
+ uint64_t u64;
+ struct cvmx_iob_outb_com_pri_cnt_s {
+ uint64_t reserved_16_63:48;
+ uint64_t cnt_enb:1;
+ uint64_t cnt_val:15;
+ } s;
+ struct cvmx_iob_outb_com_pri_cnt_s cn38xx;
+ struct cvmx_iob_outb_com_pri_cnt_s cn38xxp2;
+ struct cvmx_iob_outb_com_pri_cnt_s cn52xx;
+ struct cvmx_iob_outb_com_pri_cnt_s cn52xxp1;
+ struct cvmx_iob_outb_com_pri_cnt_s cn56xx;
+ struct cvmx_iob_outb_com_pri_cnt_s cn56xxp1;
+ struct cvmx_iob_outb_com_pri_cnt_s cn58xx;
+ struct cvmx_iob_outb_com_pri_cnt_s cn58xxp1;
+};
+
+union cvmx_iob_outb_control_match {
+ uint64_t u64;
+ struct cvmx_iob_outb_control_match_s {
+ uint64_t reserved_26_63:38;
+ uint64_t mask:8;
+ uint64_t eot:1;
+ uint64_t dst:8;
+ uint64_t src:9;
+ } s;
+ struct cvmx_iob_outb_control_match_s cn30xx;
+ struct cvmx_iob_outb_control_match_s cn31xx;
+ struct cvmx_iob_outb_control_match_s cn38xx;
+ struct cvmx_iob_outb_control_match_s cn38xxp2;
+ struct cvmx_iob_outb_control_match_s cn50xx;
+ struct cvmx_iob_outb_control_match_s cn52xx;
+ struct cvmx_iob_outb_control_match_s cn52xxp1;
+ struct cvmx_iob_outb_control_match_s cn56xx;
+ struct cvmx_iob_outb_control_match_s cn56xxp1;
+ struct cvmx_iob_outb_control_match_s cn58xx;
+ struct cvmx_iob_outb_control_match_s cn58xxp1;
+};
+
+union cvmx_iob_outb_control_match_enb {
+ uint64_t u64;
+ struct cvmx_iob_outb_control_match_enb_s {
+ uint64_t reserved_26_63:38;
+ uint64_t mask:8;
+ uint64_t eot:1;
+ uint64_t dst:8;
+ uint64_t src:9;
+ } s;
+ struct cvmx_iob_outb_control_match_enb_s cn30xx;
+ struct cvmx_iob_outb_control_match_enb_s cn31xx;
+ struct cvmx_iob_outb_control_match_enb_s cn38xx;
+ struct cvmx_iob_outb_control_match_enb_s cn38xxp2;
+ struct cvmx_iob_outb_control_match_enb_s cn50xx;
+ struct cvmx_iob_outb_control_match_enb_s cn52xx;
+ struct cvmx_iob_outb_control_match_enb_s cn52xxp1;
+ struct cvmx_iob_outb_control_match_enb_s cn56xx;
+ struct cvmx_iob_outb_control_match_enb_s cn56xxp1;
+ struct cvmx_iob_outb_control_match_enb_s cn58xx;
+ struct cvmx_iob_outb_control_match_enb_s cn58xxp1;
+};
+
+union cvmx_iob_outb_data_match {
+ uint64_t u64;
+ struct cvmx_iob_outb_data_match_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_iob_outb_data_match_s cn30xx;
+ struct cvmx_iob_outb_data_match_s cn31xx;
+ struct cvmx_iob_outb_data_match_s cn38xx;
+ struct cvmx_iob_outb_data_match_s cn38xxp2;
+ struct cvmx_iob_outb_data_match_s cn50xx;
+ struct cvmx_iob_outb_data_match_s cn52xx;
+ struct cvmx_iob_outb_data_match_s cn52xxp1;
+ struct cvmx_iob_outb_data_match_s cn56xx;
+ struct cvmx_iob_outb_data_match_s cn56xxp1;
+ struct cvmx_iob_outb_data_match_s cn58xx;
+ struct cvmx_iob_outb_data_match_s cn58xxp1;
+};
+
+union cvmx_iob_outb_data_match_enb {
+ uint64_t u64;
+ struct cvmx_iob_outb_data_match_enb_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_iob_outb_data_match_enb_s cn30xx;
+ struct cvmx_iob_outb_data_match_enb_s cn31xx;
+ struct cvmx_iob_outb_data_match_enb_s cn38xx;
+ struct cvmx_iob_outb_data_match_enb_s cn38xxp2;
+ struct cvmx_iob_outb_data_match_enb_s cn50xx;
+ struct cvmx_iob_outb_data_match_enb_s cn52xx;
+ struct cvmx_iob_outb_data_match_enb_s cn52xxp1;
+ struct cvmx_iob_outb_data_match_enb_s cn56xx;
+ struct cvmx_iob_outb_data_match_enb_s cn56xxp1;
+ struct cvmx_iob_outb_data_match_enb_s cn58xx;
+ struct cvmx_iob_outb_data_match_enb_s cn58xxp1;
+};
+
+union cvmx_iob_outb_fpa_pri_cnt {
+ uint64_t u64;
+ struct cvmx_iob_outb_fpa_pri_cnt_s {
+ uint64_t reserved_16_63:48;
+ uint64_t cnt_enb:1;
+ uint64_t cnt_val:15;
+ } s;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn38xx;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn38xxp2;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn52xx;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn52xxp1;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn56xx;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn56xxp1;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn58xx;
+ struct cvmx_iob_outb_fpa_pri_cnt_s cn58xxp1;
+};
+
+union cvmx_iob_outb_req_pri_cnt {
+ uint64_t u64;
+ struct cvmx_iob_outb_req_pri_cnt_s {
+ uint64_t reserved_16_63:48;
+ uint64_t cnt_enb:1;
+ uint64_t cnt_val:15;
+ } s;
+ struct cvmx_iob_outb_req_pri_cnt_s cn38xx;
+ struct cvmx_iob_outb_req_pri_cnt_s cn38xxp2;
+ struct cvmx_iob_outb_req_pri_cnt_s cn52xx;
+ struct cvmx_iob_outb_req_pri_cnt_s cn52xxp1;
+ struct cvmx_iob_outb_req_pri_cnt_s cn56xx;
+ struct cvmx_iob_outb_req_pri_cnt_s cn56xxp1;
+ struct cvmx_iob_outb_req_pri_cnt_s cn58xx;
+ struct cvmx_iob_outb_req_pri_cnt_s cn58xxp1;
+};
+
+union cvmx_iob_p2c_req_pri_cnt {
+ uint64_t u64;
+ struct cvmx_iob_p2c_req_pri_cnt_s {
+ uint64_t reserved_16_63:48;
+ uint64_t cnt_enb:1;
+ uint64_t cnt_val:15;
+ } s;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn38xx;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn38xxp2;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn52xx;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn52xxp1;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn56xx;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn56xxp1;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn58xx;
+ struct cvmx_iob_p2c_req_pri_cnt_s cn58xxp1;
+};
+
+union cvmx_iob_pkt_err {
+ uint64_t u64;
+ struct cvmx_iob_pkt_err_s {
+ uint64_t reserved_6_63:58;
+ uint64_t port:6;
+ } s;
+ struct cvmx_iob_pkt_err_s cn30xx;
+ struct cvmx_iob_pkt_err_s cn31xx;
+ struct cvmx_iob_pkt_err_s cn38xx;
+ struct cvmx_iob_pkt_err_s cn38xxp2;
+ struct cvmx_iob_pkt_err_s cn50xx;
+ struct cvmx_iob_pkt_err_s cn52xx;
+ struct cvmx_iob_pkt_err_s cn52xxp1;
+ struct cvmx_iob_pkt_err_s cn56xx;
+ struct cvmx_iob_pkt_err_s cn56xxp1;
+ struct cvmx_iob_pkt_err_s cn58xx;
+ struct cvmx_iob_pkt_err_s cn58xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-ipd-defs.h b/arch/mips/include/asm/octeon/cvmx-ipd-defs.h
new file mode 100644
index 0000000..f8b8fc6
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-ipd-defs.h
@@ -0,0 +1,877 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_IPD_DEFS_H__
+#define __CVMX_IPD_DEFS_H__
+
+#define CVMX_IPD_1ST_MBUFF_SKIP \
+ CVMX_ADD_IO_SEG(0x00014F0000000000ull)
+#define CVMX_IPD_1st_NEXT_PTR_BACK \
+ CVMX_ADD_IO_SEG(0x00014F0000000150ull)
+#define CVMX_IPD_2nd_NEXT_PTR_BACK \
+ CVMX_ADD_IO_SEG(0x00014F0000000158ull)
+#define CVMX_IPD_BIST_STATUS \
+ CVMX_ADD_IO_SEG(0x00014F00000007F8ull)
+#define CVMX_IPD_BP_PRT_RED_END \
+ CVMX_ADD_IO_SEG(0x00014F0000000328ull)
+#define CVMX_IPD_CLK_COUNT \
+ CVMX_ADD_IO_SEG(0x00014F0000000338ull)
+#define CVMX_IPD_CTL_STATUS \
+ CVMX_ADD_IO_SEG(0x00014F0000000018ull)
+#define CVMX_IPD_INT_ENB \
+ CVMX_ADD_IO_SEG(0x00014F0000000160ull)
+#define CVMX_IPD_INT_SUM \
+ CVMX_ADD_IO_SEG(0x00014F0000000168ull)
+#define CVMX_IPD_NOT_1ST_MBUFF_SKIP \
+ CVMX_ADD_IO_SEG(0x00014F0000000008ull)
+#define CVMX_IPD_PACKET_MBUFF_SIZE \
+ CVMX_ADD_IO_SEG(0x00014F0000000010ull)
+#define CVMX_IPD_PKT_PTR_VALID \
+ CVMX_ADD_IO_SEG(0x00014F0000000358ull)
+#define CVMX_IPD_PORTX_BP_PAGE_CNT(offset) \
+ CVMX_ADD_IO_SEG(0x00014F0000000028ull + (((offset) & 63) * 8))
+#define CVMX_IPD_PORTX_BP_PAGE_CNT2(offset) \
+ CVMX_ADD_IO_SEG(0x00014F0000000368ull + (((offset) & 63) * 8) - 8 * 36)
+#define CVMX_IPD_PORT_BP_COUNTERS2_PAIRX(offset) \
+ CVMX_ADD_IO_SEG(0x00014F0000000388ull + (((offset) & 63) * 8) - 8 * 36)
+#define CVMX_IPD_PORT_BP_COUNTERS_PAIRX(offset) \
+ CVMX_ADD_IO_SEG(0x00014F00000001B8ull + (((offset) & 63) * 8))
+#define CVMX_IPD_PORT_QOS_INTX(offset) \
+ CVMX_ADD_IO_SEG(0x00014F0000000808ull + (((offset) & 7) * 8))
+#define CVMX_IPD_PORT_QOS_INT_ENBX(offset) \
+ CVMX_ADD_IO_SEG(0x00014F0000000848ull + (((offset) & 7) * 8))
+#define CVMX_IPD_PORT_QOS_X_CNT(offset) \
+ CVMX_ADD_IO_SEG(0x00014F0000000888ull + (((offset) & 511) * 8))
+#define CVMX_IPD_PRC_HOLD_PTR_FIFO_CTL \
+ CVMX_ADD_IO_SEG(0x00014F0000000348ull)
+#define CVMX_IPD_PRC_PORT_PTR_FIFO_CTL \
+ CVMX_ADD_IO_SEG(0x00014F0000000350ull)
+#define CVMX_IPD_PTR_COUNT \
+ CVMX_ADD_IO_SEG(0x00014F0000000320ull)
+#define CVMX_IPD_PWP_PTR_FIFO_CTL \
+ CVMX_ADD_IO_SEG(0x00014F0000000340ull)
+#define CVMX_IPD_QOS0_RED_MARKS \
+ CVMX_ADD_IO_SEG(0x00014F0000000178ull)
+#define CVMX_IPD_QOS1_RED_MARKS \
+ CVMX_ADD_IO_SEG(0x00014F0000000180ull)
+#define CVMX_IPD_QOS2_RED_MARKS \
+ CVMX_ADD_IO_SEG(0x00014F0000000188ull)
+#define CVMX_IPD_QOS3_RED_MARKS \
+ CVMX_ADD_IO_SEG(0x00014F0000000190ull)
+#define CVMX_IPD_QOS4_RED_MARKS \
+ CVMX_ADD_IO_SEG(0x00014F0000000198ull)
+#define CVMX_IPD_QOS5_RED_MARKS \
+ CVMX_ADD_IO_SEG(0x00014F00000001A0ull)
+#define CVMX_IPD_QOS6_RED_MARKS \
+ CVMX_ADD_IO_SEG(0x00014F00000001A8ull)
+#define CVMX_IPD_QOS7_RED_MARKS \
+ CVMX_ADD_IO_SEG(0x00014F00000001B0ull)
+#define CVMX_IPD_QOSX_RED_MARKS(offset) \
+ CVMX_ADD_IO_SEG(0x00014F0000000178ull + (((offset) & 7) * 8))
+#define CVMX_IPD_QUE0_FREE_PAGE_CNT \
+ CVMX_ADD_IO_SEG(0x00014F0000000330ull)
+#define CVMX_IPD_RED_PORT_ENABLE \
+ CVMX_ADD_IO_SEG(0x00014F00000002D8ull)
+#define CVMX_IPD_RED_PORT_ENABLE2 \
+ CVMX_ADD_IO_SEG(0x00014F00000003A8ull)
+#define CVMX_IPD_RED_QUE0_PARAM \
+ CVMX_ADD_IO_SEG(0x00014F00000002E0ull)
+#define CVMX_IPD_RED_QUE1_PARAM \
+ CVMX_ADD_IO_SEG(0x00014F00000002E8ull)
+#define CVMX_IPD_RED_QUE2_PARAM \
+ CVMX_ADD_IO_SEG(0x00014F00000002F0ull)
+#define CVMX_IPD_RED_QUE3_PARAM \
+ CVMX_ADD_IO_SEG(0x00014F00000002F8ull)
+#define CVMX_IPD_RED_QUE4_PARAM \
+ CVMX_ADD_IO_SEG(0x00014F0000000300ull)
+#define CVMX_IPD_RED_QUE5_PARAM \
+ CVMX_ADD_IO_SEG(0x00014F0000000308ull)
+#define CVMX_IPD_RED_QUE6_PARAM \
+ CVMX_ADD_IO_SEG(0x00014F0000000310ull)
+#define CVMX_IPD_RED_QUE7_PARAM \
+ CVMX_ADD_IO_SEG(0x00014F0000000318ull)
+#define CVMX_IPD_RED_QUEX_PARAM(offset) \
+ CVMX_ADD_IO_SEG(0x00014F00000002E0ull + (((offset) & 7) * 8))
+#define CVMX_IPD_SUB_PORT_BP_PAGE_CNT \
+ CVMX_ADD_IO_SEG(0x00014F0000000148ull)
+#define CVMX_IPD_SUB_PORT_FCS \
+ CVMX_ADD_IO_SEG(0x00014F0000000170ull)
+#define CVMX_IPD_SUB_PORT_QOS_CNT \
+ CVMX_ADD_IO_SEG(0x00014F0000000800ull)
+#define CVMX_IPD_WQE_FPA_QUEUE \
+ CVMX_ADD_IO_SEG(0x00014F0000000020ull)
+#define CVMX_IPD_WQE_PTR_VALID \
+ CVMX_ADD_IO_SEG(0x00014F0000000360ull)
+
+union cvmx_ipd_1st_mbuff_skip {
+ uint64_t u64;
+ struct cvmx_ipd_1st_mbuff_skip_s {
+ uint64_t reserved_6_63:58;
+ uint64_t skip_sz:6;
+ } s;
+ struct cvmx_ipd_1st_mbuff_skip_s cn30xx;
+ struct cvmx_ipd_1st_mbuff_skip_s cn31xx;
+ struct cvmx_ipd_1st_mbuff_skip_s cn38xx;
+ struct cvmx_ipd_1st_mbuff_skip_s cn38xxp2;
+ struct cvmx_ipd_1st_mbuff_skip_s cn50xx;
+ struct cvmx_ipd_1st_mbuff_skip_s cn52xx;
+ struct cvmx_ipd_1st_mbuff_skip_s cn52xxp1;
+ struct cvmx_ipd_1st_mbuff_skip_s cn56xx;
+ struct cvmx_ipd_1st_mbuff_skip_s cn56xxp1;
+ struct cvmx_ipd_1st_mbuff_skip_s cn58xx;
+ struct cvmx_ipd_1st_mbuff_skip_s cn58xxp1;
+};
+
+union cvmx_ipd_1st_next_ptr_back {
+ uint64_t u64;
+ struct cvmx_ipd_1st_next_ptr_back_s {
+ uint64_t reserved_4_63:60;
+ uint64_t back:4;
+ } s;
+ struct cvmx_ipd_1st_next_ptr_back_s cn30xx;
+ struct cvmx_ipd_1st_next_ptr_back_s cn31xx;
+ struct cvmx_ipd_1st_next_ptr_back_s cn38xx;
+ struct cvmx_ipd_1st_next_ptr_back_s cn38xxp2;
+ struct cvmx_ipd_1st_next_ptr_back_s cn50xx;
+ struct cvmx_ipd_1st_next_ptr_back_s cn52xx;
+ struct cvmx_ipd_1st_next_ptr_back_s cn52xxp1;
+ struct cvmx_ipd_1st_next_ptr_back_s cn56xx;
+ struct cvmx_ipd_1st_next_ptr_back_s cn56xxp1;
+ struct cvmx_ipd_1st_next_ptr_back_s cn58xx;
+ struct cvmx_ipd_1st_next_ptr_back_s cn58xxp1;
+};
+
+union cvmx_ipd_2nd_next_ptr_back {
+ uint64_t u64;
+ struct cvmx_ipd_2nd_next_ptr_back_s {
+ uint64_t reserved_4_63:60;
+ uint64_t back:4;
+ } s;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn30xx;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn31xx;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn38xx;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn38xxp2;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn50xx;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn52xx;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn52xxp1;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn56xx;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn56xxp1;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn58xx;
+ struct cvmx_ipd_2nd_next_ptr_back_s cn58xxp1;
+};
+
+union cvmx_ipd_bist_status {
+ uint64_t u64;
+ struct cvmx_ipd_bist_status_s {
+ uint64_t reserved_18_63:46;
+ uint64_t csr_mem:1;
+ uint64_t csr_ncmd:1;
+ uint64_t pwq_wqed:1;
+ uint64_t pwq_wp1:1;
+ uint64_t pwq_pow:1;
+ uint64_t ipq_pbe1:1;
+ uint64_t ipq_pbe0:1;
+ uint64_t pbm3:1;
+ uint64_t pbm2:1;
+ uint64_t pbm1:1;
+ uint64_t pbm0:1;
+ uint64_t pbm_word:1;
+ uint64_t pwq1:1;
+ uint64_t pwq0:1;
+ uint64_t prc_off:1;
+ uint64_t ipd_old:1;
+ uint64_t ipd_new:1;
+ uint64_t pwp:1;
+ } s;
+ struct cvmx_ipd_bist_status_cn30xx {
+ uint64_t reserved_16_63:48;
+ uint64_t pwq_wqed:1;
+ uint64_t pwq_wp1:1;
+ uint64_t pwq_pow:1;
+ uint64_t ipq_pbe1:1;
+ uint64_t ipq_pbe0:1;
+ uint64_t pbm3:1;
+ uint64_t pbm2:1;
+ uint64_t pbm1:1;
+ uint64_t pbm0:1;
+ uint64_t pbm_word:1;
+ uint64_t pwq1:1;
+ uint64_t pwq0:1;
+ uint64_t prc_off:1;
+ uint64_t ipd_old:1;
+ uint64_t ipd_new:1;
+ uint64_t pwp:1;
+ } cn30xx;
+ struct cvmx_ipd_bist_status_cn30xx cn31xx;
+ struct cvmx_ipd_bist_status_cn30xx cn38xx;
+ struct cvmx_ipd_bist_status_cn30xx cn38xxp2;
+ struct cvmx_ipd_bist_status_cn30xx cn50xx;
+ struct cvmx_ipd_bist_status_s cn52xx;
+ struct cvmx_ipd_bist_status_s cn52xxp1;
+ struct cvmx_ipd_bist_status_s cn56xx;
+ struct cvmx_ipd_bist_status_s cn56xxp1;
+ struct cvmx_ipd_bist_status_cn30xx cn58xx;
+ struct cvmx_ipd_bist_status_cn30xx cn58xxp1;
+};
+
+union cvmx_ipd_bp_prt_red_end {
+ uint64_t u64;
+ struct cvmx_ipd_bp_prt_red_end_s {
+ uint64_t reserved_40_63:24;
+ uint64_t prt_enb:40;
+ } s;
+ struct cvmx_ipd_bp_prt_red_end_cn30xx {
+ uint64_t reserved_36_63:28;
+ uint64_t prt_enb:36;
+ } cn30xx;
+ struct cvmx_ipd_bp_prt_red_end_cn30xx cn31xx;
+ struct cvmx_ipd_bp_prt_red_end_cn30xx cn38xx;
+ struct cvmx_ipd_bp_prt_red_end_cn30xx cn38xxp2;
+ struct cvmx_ipd_bp_prt_red_end_cn30xx cn50xx;
+ struct cvmx_ipd_bp_prt_red_end_s cn52xx;
+ struct cvmx_ipd_bp_prt_red_end_s cn52xxp1;
+ struct cvmx_ipd_bp_prt_red_end_s cn56xx;
+ struct cvmx_ipd_bp_prt_red_end_s cn56xxp1;
+ struct cvmx_ipd_bp_prt_red_end_cn30xx cn58xx;
+ struct cvmx_ipd_bp_prt_red_end_cn30xx cn58xxp1;
+};
+
+union cvmx_ipd_clk_count {
+ uint64_t u64;
+ struct cvmx_ipd_clk_count_s {
+ uint64_t clk_cnt:64;
+ } s;
+ struct cvmx_ipd_clk_count_s cn30xx;
+ struct cvmx_ipd_clk_count_s cn31xx;
+ struct cvmx_ipd_clk_count_s cn38xx;
+ struct cvmx_ipd_clk_count_s cn38xxp2;
+ struct cvmx_ipd_clk_count_s cn50xx;
+ struct cvmx_ipd_clk_count_s cn52xx;
+ struct cvmx_ipd_clk_count_s cn52xxp1;
+ struct cvmx_ipd_clk_count_s cn56xx;
+ struct cvmx_ipd_clk_count_s cn56xxp1;
+ struct cvmx_ipd_clk_count_s cn58xx;
+ struct cvmx_ipd_clk_count_s cn58xxp1;
+};
+
+union cvmx_ipd_ctl_status {
+ uint64_t u64;
+ struct cvmx_ipd_ctl_status_s {
+ uint64_t reserved_15_63:49;
+ uint64_t no_wptr:1;
+ uint64_t pq_apkt:1;
+ uint64_t pq_nabuf:1;
+ uint64_t ipd_full:1;
+ uint64_t pkt_off:1;
+ uint64_t len_m8:1;
+ uint64_t reset:1;
+ uint64_t addpkt:1;
+ uint64_t naddbuf:1;
+ uint64_t pkt_lend:1;
+ uint64_t wqe_lend:1;
+ uint64_t pbp_en:1;
+ uint64_t opc_mode:2;
+ uint64_t ipd_en:1;
+ } s;
+ struct cvmx_ipd_ctl_status_cn30xx {
+ uint64_t reserved_10_63:54;
+ uint64_t len_m8:1;
+ uint64_t reset:1;
+ uint64_t addpkt:1;
+ uint64_t naddbuf:1;
+ uint64_t pkt_lend:1;
+ uint64_t wqe_lend:1;
+ uint64_t pbp_en:1;
+ uint64_t opc_mode:2;
+ uint64_t ipd_en:1;
+ } cn30xx;
+ struct cvmx_ipd_ctl_status_cn30xx cn31xx;
+ struct cvmx_ipd_ctl_status_cn30xx cn38xx;
+ struct cvmx_ipd_ctl_status_cn38xxp2 {
+ uint64_t reserved_9_63:55;
+ uint64_t reset:1;
+ uint64_t addpkt:1;
+ uint64_t naddbuf:1;
+ uint64_t pkt_lend:1;
+ uint64_t wqe_lend:1;
+ uint64_t pbp_en:1;
+ uint64_t opc_mode:2;
+ uint64_t ipd_en:1;
+ } cn38xxp2;
+ struct cvmx_ipd_ctl_status_s cn50xx;
+ struct cvmx_ipd_ctl_status_s cn52xx;
+ struct cvmx_ipd_ctl_status_s cn52xxp1;
+ struct cvmx_ipd_ctl_status_s cn56xx;
+ struct cvmx_ipd_ctl_status_s cn56xxp1;
+ struct cvmx_ipd_ctl_status_cn58xx {
+ uint64_t reserved_12_63:52;
+ uint64_t ipd_full:1;
+ uint64_t pkt_off:1;
+ uint64_t len_m8:1;
+ uint64_t reset:1;
+ uint64_t addpkt:1;
+ uint64_t naddbuf:1;
+ uint64_t pkt_lend:1;
+ uint64_t wqe_lend:1;
+ uint64_t pbp_en:1;
+ uint64_t opc_mode:2;
+ uint64_t ipd_en:1;
+ } cn58xx;
+ struct cvmx_ipd_ctl_status_cn58xx cn58xxp1;
+};
+
+union cvmx_ipd_int_enb {
+ uint64_t u64;
+ struct cvmx_ipd_int_enb_s {
+ uint64_t reserved_12_63:52;
+ uint64_t pq_sub:1;
+ uint64_t pq_add:1;
+ uint64_t bc_ovr:1;
+ uint64_t d_coll:1;
+ uint64_t c_coll:1;
+ uint64_t cc_ovr:1;
+ uint64_t dc_ovr:1;
+ uint64_t bp_sub:1;
+ uint64_t prc_par3:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par0:1;
+ } s;
+ struct cvmx_ipd_int_enb_cn30xx {
+ uint64_t reserved_5_63:59;
+ uint64_t bp_sub:1;
+ uint64_t prc_par3:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par0:1;
+ } cn30xx;
+ struct cvmx_ipd_int_enb_cn30xx cn31xx;
+ struct cvmx_ipd_int_enb_cn38xx {
+ uint64_t reserved_10_63:54;
+ uint64_t bc_ovr:1;
+ uint64_t d_coll:1;
+ uint64_t c_coll:1;
+ uint64_t cc_ovr:1;
+ uint64_t dc_ovr:1;
+ uint64_t bp_sub:1;
+ uint64_t prc_par3:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par0:1;
+ } cn38xx;
+ struct cvmx_ipd_int_enb_cn30xx cn38xxp2;
+ struct cvmx_ipd_int_enb_cn38xx cn50xx;
+ struct cvmx_ipd_int_enb_s cn52xx;
+ struct cvmx_ipd_int_enb_s cn52xxp1;
+ struct cvmx_ipd_int_enb_s cn56xx;
+ struct cvmx_ipd_int_enb_s cn56xxp1;
+ struct cvmx_ipd_int_enb_cn38xx cn58xx;
+ struct cvmx_ipd_int_enb_cn38xx cn58xxp1;
+};
+
+union cvmx_ipd_int_sum {
+ uint64_t u64;
+ struct cvmx_ipd_int_sum_s {
+ uint64_t reserved_12_63:52;
+ uint64_t pq_sub:1;
+ uint64_t pq_add:1;
+ uint64_t bc_ovr:1;
+ uint64_t d_coll:1;
+ uint64_t c_coll:1;
+ uint64_t cc_ovr:1;
+ uint64_t dc_ovr:1;
+ uint64_t bp_sub:1;
+ uint64_t prc_par3:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par0:1;
+ } s;
+ struct cvmx_ipd_int_sum_cn30xx {
+ uint64_t reserved_5_63:59;
+ uint64_t bp_sub:1;
+ uint64_t prc_par3:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par0:1;
+ } cn30xx;
+ struct cvmx_ipd_int_sum_cn30xx cn31xx;
+ struct cvmx_ipd_int_sum_cn38xx {
+ uint64_t reserved_10_63:54;
+ uint64_t bc_ovr:1;
+ uint64_t d_coll:1;
+ uint64_t c_coll:1;
+ uint64_t cc_ovr:1;
+ uint64_t dc_ovr:1;
+ uint64_t bp_sub:1;
+ uint64_t prc_par3:1;
+ uint64_t prc_par2:1;
+ uint64_t prc_par1:1;
+ uint64_t prc_par0:1;
+ } cn38xx;
+ struct cvmx_ipd_int_sum_cn30xx cn38xxp2;
+ struct cvmx_ipd_int_sum_cn38xx cn50xx;
+ struct cvmx_ipd_int_sum_s cn52xx;
+ struct cvmx_ipd_int_sum_s cn52xxp1;
+ struct cvmx_ipd_int_sum_s cn56xx;
+ struct cvmx_ipd_int_sum_s cn56xxp1;
+ struct cvmx_ipd_int_sum_cn38xx cn58xx;
+ struct cvmx_ipd_int_sum_cn38xx cn58xxp1;
+};
+
+union cvmx_ipd_not_1st_mbuff_skip {
+ uint64_t u64;
+ struct cvmx_ipd_not_1st_mbuff_skip_s {
+ uint64_t reserved_6_63:58;
+ uint64_t skip_sz:6;
+ } s;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn30xx;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn31xx;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn38xx;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn38xxp2;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn50xx;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn52xx;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn52xxp1;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn56xx;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn56xxp1;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn58xx;
+ struct cvmx_ipd_not_1st_mbuff_skip_s cn58xxp1;
+};
+
+union cvmx_ipd_packet_mbuff_size {
+ uint64_t u64;
+ struct cvmx_ipd_packet_mbuff_size_s {
+ uint64_t reserved_12_63:52;
+ uint64_t mb_size:12;
+ } s;
+ struct cvmx_ipd_packet_mbuff_size_s cn30xx;
+ struct cvmx_ipd_packet_mbuff_size_s cn31xx;
+ struct cvmx_ipd_packet_mbuff_size_s cn38xx;
+ struct cvmx_ipd_packet_mbuff_size_s cn38xxp2;
+ struct cvmx_ipd_packet_mbuff_size_s cn50xx;
+ struct cvmx_ipd_packet_mbuff_size_s cn52xx;
+ struct cvmx_ipd_packet_mbuff_size_s cn52xxp1;
+ struct cvmx_ipd_packet_mbuff_size_s cn56xx;
+ struct cvmx_ipd_packet_mbuff_size_s cn56xxp1;
+ struct cvmx_ipd_packet_mbuff_size_s cn58xx;
+ struct cvmx_ipd_packet_mbuff_size_s cn58xxp1;
+};
+
+union cvmx_ipd_pkt_ptr_valid {
+ uint64_t u64;
+ struct cvmx_ipd_pkt_ptr_valid_s {
+ uint64_t reserved_29_63:35;
+ uint64_t ptr:29;
+ } s;
+ struct cvmx_ipd_pkt_ptr_valid_s cn30xx;
+ struct cvmx_ipd_pkt_ptr_valid_s cn31xx;
+ struct cvmx_ipd_pkt_ptr_valid_s cn38xx;
+ struct cvmx_ipd_pkt_ptr_valid_s cn50xx;
+ struct cvmx_ipd_pkt_ptr_valid_s cn52xx;
+ struct cvmx_ipd_pkt_ptr_valid_s cn52xxp1;
+ struct cvmx_ipd_pkt_ptr_valid_s cn56xx;
+ struct cvmx_ipd_pkt_ptr_valid_s cn56xxp1;
+ struct cvmx_ipd_pkt_ptr_valid_s cn58xx;
+ struct cvmx_ipd_pkt_ptr_valid_s cn58xxp1;
+};
+
+union cvmx_ipd_portx_bp_page_cnt {
+ uint64_t u64;
+ struct cvmx_ipd_portx_bp_page_cnt_s {
+ uint64_t reserved_18_63:46;
+ uint64_t bp_enb:1;
+ uint64_t page_cnt:17;
+ } s;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn30xx;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn31xx;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn38xx;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn38xxp2;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn50xx;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn52xx;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn52xxp1;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn56xx;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn56xxp1;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn58xx;
+ struct cvmx_ipd_portx_bp_page_cnt_s cn58xxp1;
+};
+
+union cvmx_ipd_portx_bp_page_cnt2 {
+ uint64_t u64;
+ struct cvmx_ipd_portx_bp_page_cnt2_s {
+ uint64_t reserved_18_63:46;
+ uint64_t bp_enb:1;
+ uint64_t page_cnt:17;
+ } s;
+ struct cvmx_ipd_portx_bp_page_cnt2_s cn52xx;
+ struct cvmx_ipd_portx_bp_page_cnt2_s cn52xxp1;
+ struct cvmx_ipd_portx_bp_page_cnt2_s cn56xx;
+ struct cvmx_ipd_portx_bp_page_cnt2_s cn56xxp1;
+};
+
+union cvmx_ipd_port_bp_counters2_pairx {
+ uint64_t u64;
+ struct cvmx_ipd_port_bp_counters2_pairx_s {
+ uint64_t reserved_25_63:39;
+ uint64_t cnt_val:25;
+ } s;
+ struct cvmx_ipd_port_bp_counters2_pairx_s cn52xx;
+ struct cvmx_ipd_port_bp_counters2_pairx_s cn52xxp1;
+ struct cvmx_ipd_port_bp_counters2_pairx_s cn56xx;
+ struct cvmx_ipd_port_bp_counters2_pairx_s cn56xxp1;
+};
+
+union cvmx_ipd_port_bp_counters_pairx {
+ uint64_t u64;
+ struct cvmx_ipd_port_bp_counters_pairx_s {
+ uint64_t reserved_25_63:39;
+ uint64_t cnt_val:25;
+ } s;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn30xx;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn31xx;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn38xx;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn38xxp2;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn50xx;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn52xx;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn52xxp1;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn56xx;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn56xxp1;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn58xx;
+ struct cvmx_ipd_port_bp_counters_pairx_s cn58xxp1;
+};
+
+union cvmx_ipd_port_qos_x_cnt {
+ uint64_t u64;
+ struct cvmx_ipd_port_qos_x_cnt_s {
+ uint64_t wmark:32;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_ipd_port_qos_x_cnt_s cn52xx;
+ struct cvmx_ipd_port_qos_x_cnt_s cn52xxp1;
+ struct cvmx_ipd_port_qos_x_cnt_s cn56xx;
+ struct cvmx_ipd_port_qos_x_cnt_s cn56xxp1;
+};
+
+union cvmx_ipd_port_qos_intx {
+ uint64_t u64;
+ struct cvmx_ipd_port_qos_intx_s {
+ uint64_t intr:64;
+ } s;
+ struct cvmx_ipd_port_qos_intx_s cn52xx;
+ struct cvmx_ipd_port_qos_intx_s cn52xxp1;
+ struct cvmx_ipd_port_qos_intx_s cn56xx;
+ struct cvmx_ipd_port_qos_intx_s cn56xxp1;
+};
+
+union cvmx_ipd_port_qos_int_enbx {
+ uint64_t u64;
+ struct cvmx_ipd_port_qos_int_enbx_s {
+ uint64_t enb:64;
+ } s;
+ struct cvmx_ipd_port_qos_int_enbx_s cn52xx;
+ struct cvmx_ipd_port_qos_int_enbx_s cn52xxp1;
+ struct cvmx_ipd_port_qos_int_enbx_s cn56xx;
+ struct cvmx_ipd_port_qos_int_enbx_s cn56xxp1;
+};
+
+union cvmx_ipd_prc_hold_ptr_fifo_ctl {
+ uint64_t u64;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s {
+ uint64_t reserved_39_63:25;
+ uint64_t max_pkt:3;
+ uint64_t praddr:3;
+ uint64_t ptr:29;
+ uint64_t cena:1;
+ uint64_t raddr:3;
+ } s;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn30xx;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn31xx;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn38xx;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn50xx;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn52xx;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn52xxp1;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn56xx;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn56xxp1;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn58xx;
+ struct cvmx_ipd_prc_hold_ptr_fifo_ctl_s cn58xxp1;
+};
+
+union cvmx_ipd_prc_port_ptr_fifo_ctl {
+ uint64_t u64;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s {
+ uint64_t reserved_44_63:20;
+ uint64_t max_pkt:7;
+ uint64_t ptr:29;
+ uint64_t cena:1;
+ uint64_t raddr:7;
+ } s;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn30xx;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn31xx;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn38xx;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn50xx;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn52xx;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn52xxp1;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn56xx;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn56xxp1;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn58xx;
+ struct cvmx_ipd_prc_port_ptr_fifo_ctl_s cn58xxp1;
+};
+
+union cvmx_ipd_ptr_count {
+ uint64_t u64;
+ struct cvmx_ipd_ptr_count_s {
+ uint64_t reserved_19_63:45;
+ uint64_t pktv_cnt:1;
+ uint64_t wqev_cnt:1;
+ uint64_t pfif_cnt:3;
+ uint64_t pkt_pcnt:7;
+ uint64_t wqe_pcnt:7;
+ } s;
+ struct cvmx_ipd_ptr_count_s cn30xx;
+ struct cvmx_ipd_ptr_count_s cn31xx;
+ struct cvmx_ipd_ptr_count_s cn38xx;
+ struct cvmx_ipd_ptr_count_s cn38xxp2;
+ struct cvmx_ipd_ptr_count_s cn50xx;
+ struct cvmx_ipd_ptr_count_s cn52xx;
+ struct cvmx_ipd_ptr_count_s cn52xxp1;
+ struct cvmx_ipd_ptr_count_s cn56xx;
+ struct cvmx_ipd_ptr_count_s cn56xxp1;
+ struct cvmx_ipd_ptr_count_s cn58xx;
+ struct cvmx_ipd_ptr_count_s cn58xxp1;
+};
+
+union cvmx_ipd_pwp_ptr_fifo_ctl {
+ uint64_t u64;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s {
+ uint64_t reserved_61_63:3;
+ uint64_t max_cnts:7;
+ uint64_t wraddr:8;
+ uint64_t praddr:8;
+ uint64_t ptr:29;
+ uint64_t cena:1;
+ uint64_t raddr:8;
+ } s;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn30xx;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn31xx;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn38xx;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn50xx;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn52xx;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn52xxp1;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn56xx;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn56xxp1;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn58xx;
+ struct cvmx_ipd_pwp_ptr_fifo_ctl_s cn58xxp1;
+};
+
+union cvmx_ipd_qosx_red_marks {
+ uint64_t u64;
+ struct cvmx_ipd_qosx_red_marks_s {
+ uint64_t drop:32;
+ uint64_t pass:32;
+ } s;
+ struct cvmx_ipd_qosx_red_marks_s cn30xx;
+ struct cvmx_ipd_qosx_red_marks_s cn31xx;
+ struct cvmx_ipd_qosx_red_marks_s cn38xx;
+ struct cvmx_ipd_qosx_red_marks_s cn38xxp2;
+ struct cvmx_ipd_qosx_red_marks_s cn50xx;
+ struct cvmx_ipd_qosx_red_marks_s cn52xx;
+ struct cvmx_ipd_qosx_red_marks_s cn52xxp1;
+ struct cvmx_ipd_qosx_red_marks_s cn56xx;
+ struct cvmx_ipd_qosx_red_marks_s cn56xxp1;
+ struct cvmx_ipd_qosx_red_marks_s cn58xx;
+ struct cvmx_ipd_qosx_red_marks_s cn58xxp1;
+};
+
+union cvmx_ipd_que0_free_page_cnt {
+ uint64_t u64;
+ struct cvmx_ipd_que0_free_page_cnt_s {
+ uint64_t reserved_32_63:32;
+ uint64_t q0_pcnt:32;
+ } s;
+ struct cvmx_ipd_que0_free_page_cnt_s cn30xx;
+ struct cvmx_ipd_que0_free_page_cnt_s cn31xx;
+ struct cvmx_ipd_que0_free_page_cnt_s cn38xx;
+ struct cvmx_ipd_que0_free_page_cnt_s cn38xxp2;
+ struct cvmx_ipd_que0_free_page_cnt_s cn50xx;
+ struct cvmx_ipd_que0_free_page_cnt_s cn52xx;
+ struct cvmx_ipd_que0_free_page_cnt_s cn52xxp1;
+ struct cvmx_ipd_que0_free_page_cnt_s cn56xx;
+ struct cvmx_ipd_que0_free_page_cnt_s cn56xxp1;
+ struct cvmx_ipd_que0_free_page_cnt_s cn58xx;
+ struct cvmx_ipd_que0_free_page_cnt_s cn58xxp1;
+};
+
+union cvmx_ipd_red_port_enable {
+ uint64_t u64;
+ struct cvmx_ipd_red_port_enable_s {
+ uint64_t prb_dly:14;
+ uint64_t avg_dly:14;
+ uint64_t prt_enb:36;
+ } s;
+ struct cvmx_ipd_red_port_enable_s cn30xx;
+ struct cvmx_ipd_red_port_enable_s cn31xx;
+ struct cvmx_ipd_red_port_enable_s cn38xx;
+ struct cvmx_ipd_red_port_enable_s cn38xxp2;
+ struct cvmx_ipd_red_port_enable_s cn50xx;
+ struct cvmx_ipd_red_port_enable_s cn52xx;
+ struct cvmx_ipd_red_port_enable_s cn52xxp1;
+ struct cvmx_ipd_red_port_enable_s cn56xx;
+ struct cvmx_ipd_red_port_enable_s cn56xxp1;
+ struct cvmx_ipd_red_port_enable_s cn58xx;
+ struct cvmx_ipd_red_port_enable_s cn58xxp1;
+};
+
+union cvmx_ipd_red_port_enable2 {
+ uint64_t u64;
+ struct cvmx_ipd_red_port_enable2_s {
+ uint64_t reserved_4_63:60;
+ uint64_t prt_enb:4;
+ } s;
+ struct cvmx_ipd_red_port_enable2_s cn52xx;
+ struct cvmx_ipd_red_port_enable2_s cn52xxp1;
+ struct cvmx_ipd_red_port_enable2_s cn56xx;
+ struct cvmx_ipd_red_port_enable2_s cn56xxp1;
+};
+
+union cvmx_ipd_red_quex_param {
+ uint64_t u64;
+ struct cvmx_ipd_red_quex_param_s {
+ uint64_t reserved_49_63:15;
+ uint64_t use_pcnt:1;
+ uint64_t new_con:8;
+ uint64_t avg_con:8;
+ uint64_t prb_con:32;
+ } s;
+ struct cvmx_ipd_red_quex_param_s cn30xx;
+ struct cvmx_ipd_red_quex_param_s cn31xx;
+ struct cvmx_ipd_red_quex_param_s cn38xx;
+ struct cvmx_ipd_red_quex_param_s cn38xxp2;
+ struct cvmx_ipd_red_quex_param_s cn50xx;
+ struct cvmx_ipd_red_quex_param_s cn52xx;
+ struct cvmx_ipd_red_quex_param_s cn52xxp1;
+ struct cvmx_ipd_red_quex_param_s cn56xx;
+ struct cvmx_ipd_red_quex_param_s cn56xxp1;
+ struct cvmx_ipd_red_quex_param_s cn58xx;
+ struct cvmx_ipd_red_quex_param_s cn58xxp1;
+};
+
+union cvmx_ipd_sub_port_bp_page_cnt {
+ uint64_t u64;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s {
+ uint64_t reserved_31_63:33;
+ uint64_t port:6;
+ uint64_t page_cnt:25;
+ } s;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn30xx;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn31xx;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn38xx;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn38xxp2;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn50xx;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn52xx;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn52xxp1;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn56xx;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn56xxp1;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn58xx;
+ struct cvmx_ipd_sub_port_bp_page_cnt_s cn58xxp1;
+};
+
+union cvmx_ipd_sub_port_fcs {
+ uint64_t u64;
+ struct cvmx_ipd_sub_port_fcs_s {
+ uint64_t reserved_40_63:24;
+ uint64_t port_bit2:4;
+ uint64_t reserved_32_35:4;
+ uint64_t port_bit:32;
+ } s;
+ struct cvmx_ipd_sub_port_fcs_cn30xx {
+ uint64_t reserved_3_63:61;
+ uint64_t port_bit:3;
+ } cn30xx;
+ struct cvmx_ipd_sub_port_fcs_cn30xx cn31xx;
+ struct cvmx_ipd_sub_port_fcs_cn38xx {
+ uint64_t reserved_32_63:32;
+ uint64_t port_bit:32;
+ } cn38xx;
+ struct cvmx_ipd_sub_port_fcs_cn38xx cn38xxp2;
+ struct cvmx_ipd_sub_port_fcs_cn30xx cn50xx;
+ struct cvmx_ipd_sub_port_fcs_s cn52xx;
+ struct cvmx_ipd_sub_port_fcs_s cn52xxp1;
+ struct cvmx_ipd_sub_port_fcs_s cn56xx;
+ struct cvmx_ipd_sub_port_fcs_s cn56xxp1;
+ struct cvmx_ipd_sub_port_fcs_cn38xx cn58xx;
+ struct cvmx_ipd_sub_port_fcs_cn38xx cn58xxp1;
+};
+
+union cvmx_ipd_sub_port_qos_cnt {
+ uint64_t u64;
+ struct cvmx_ipd_sub_port_qos_cnt_s {
+ uint64_t reserved_41_63:23;
+ uint64_t port_qos:9;
+ uint64_t cnt:32;
+ } s;
+ struct cvmx_ipd_sub_port_qos_cnt_s cn52xx;
+ struct cvmx_ipd_sub_port_qos_cnt_s cn52xxp1;
+ struct cvmx_ipd_sub_port_qos_cnt_s cn56xx;
+ struct cvmx_ipd_sub_port_qos_cnt_s cn56xxp1;
+};
+
+union cvmx_ipd_wqe_fpa_queue {
+ uint64_t u64;
+ struct cvmx_ipd_wqe_fpa_queue_s {
+ uint64_t reserved_3_63:61;
+ uint64_t wqe_pool:3;
+ } s;
+ struct cvmx_ipd_wqe_fpa_queue_s cn30xx;
+ struct cvmx_ipd_wqe_fpa_queue_s cn31xx;
+ struct cvmx_ipd_wqe_fpa_queue_s cn38xx;
+ struct cvmx_ipd_wqe_fpa_queue_s cn38xxp2;
+ struct cvmx_ipd_wqe_fpa_queue_s cn50xx;
+ struct cvmx_ipd_wqe_fpa_queue_s cn52xx;
+ struct cvmx_ipd_wqe_fpa_queue_s cn52xxp1;
+ struct cvmx_ipd_wqe_fpa_queue_s cn56xx;
+ struct cvmx_ipd_wqe_fpa_queue_s cn56xxp1;
+ struct cvmx_ipd_wqe_fpa_queue_s cn58xx;
+ struct cvmx_ipd_wqe_fpa_queue_s cn58xxp1;
+};
+
+union cvmx_ipd_wqe_ptr_valid {
+ uint64_t u64;
+ struct cvmx_ipd_wqe_ptr_valid_s {
+ uint64_t reserved_29_63:35;
+ uint64_t ptr:29;
+ } s;
+ struct cvmx_ipd_wqe_ptr_valid_s cn30xx;
+ struct cvmx_ipd_wqe_ptr_valid_s cn31xx;
+ struct cvmx_ipd_wqe_ptr_valid_s cn38xx;
+ struct cvmx_ipd_wqe_ptr_valid_s cn50xx;
+ struct cvmx_ipd_wqe_ptr_valid_s cn52xx;
+ struct cvmx_ipd_wqe_ptr_valid_s cn52xxp1;
+ struct cvmx_ipd_wqe_ptr_valid_s cn56xx;
+ struct cvmx_ipd_wqe_ptr_valid_s cn56xxp1;
+ struct cvmx_ipd_wqe_ptr_valid_s cn58xx;
+ struct cvmx_ipd_wqe_ptr_valid_s cn58xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-l2c-defs.h b/arch/mips/include/asm/octeon/cvmx-l2c-defs.h
new file mode 100644
index 0000000..3375838
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-l2c-defs.h
@@ -0,0 +1,963 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_L2C_DEFS_H__
+#define __CVMX_L2C_DEFS_H__
+
+#define CVMX_L2C_BST0 \
+ CVMX_ADD_IO_SEG(0x00011800800007F8ull)
+#define CVMX_L2C_BST1 \
+ CVMX_ADD_IO_SEG(0x00011800800007F0ull)
+#define CVMX_L2C_BST2 \
+ CVMX_ADD_IO_SEG(0x00011800800007E8ull)
+#define CVMX_L2C_CFG \
+ CVMX_ADD_IO_SEG(0x0001180080000000ull)
+#define CVMX_L2C_DBG \
+ CVMX_ADD_IO_SEG(0x0001180080000030ull)
+#define CVMX_L2C_DUT \
+ CVMX_ADD_IO_SEG(0x0001180080000050ull)
+#define CVMX_L2C_GRPWRR0 \
+ CVMX_ADD_IO_SEG(0x00011800800000C8ull)
+#define CVMX_L2C_GRPWRR1 \
+ CVMX_ADD_IO_SEG(0x00011800800000D0ull)
+#define CVMX_L2C_INT_EN \
+ CVMX_ADD_IO_SEG(0x0001180080000100ull)
+#define CVMX_L2C_INT_STAT \
+ CVMX_ADD_IO_SEG(0x00011800800000F8ull)
+#define CVMX_L2C_LCKBASE \
+ CVMX_ADD_IO_SEG(0x0001180080000058ull)
+#define CVMX_L2C_LCKOFF \
+ CVMX_ADD_IO_SEG(0x0001180080000060ull)
+#define CVMX_L2C_LFB0 \
+ CVMX_ADD_IO_SEG(0x0001180080000038ull)
+#define CVMX_L2C_LFB1 \
+ CVMX_ADD_IO_SEG(0x0001180080000040ull)
+#define CVMX_L2C_LFB2 \
+ CVMX_ADD_IO_SEG(0x0001180080000048ull)
+#define CVMX_L2C_LFB3 \
+ CVMX_ADD_IO_SEG(0x00011800800000B8ull)
+#define CVMX_L2C_OOB \
+ CVMX_ADD_IO_SEG(0x00011800800000D8ull)
+#define CVMX_L2C_OOB1 \
+ CVMX_ADD_IO_SEG(0x00011800800000E0ull)
+#define CVMX_L2C_OOB2 \
+ CVMX_ADD_IO_SEG(0x00011800800000E8ull)
+#define CVMX_L2C_OOB3 \
+ CVMX_ADD_IO_SEG(0x00011800800000F0ull)
+#define CVMX_L2C_PFC0 \
+ CVMX_ADD_IO_SEG(0x0001180080000098ull)
+#define CVMX_L2C_PFC1 \
+ CVMX_ADD_IO_SEG(0x00011800800000A0ull)
+#define CVMX_L2C_PFC2 \
+ CVMX_ADD_IO_SEG(0x00011800800000A8ull)
+#define CVMX_L2C_PFC3 \
+ CVMX_ADD_IO_SEG(0x00011800800000B0ull)
+#define CVMX_L2C_PFCTL \
+ CVMX_ADD_IO_SEG(0x0001180080000090ull)
+#define CVMX_L2C_PFCX(offset) \
+ CVMX_ADD_IO_SEG(0x0001180080000098ull + (((offset) & 3) * 8))
+#define CVMX_L2C_PPGRP \
+ CVMX_ADD_IO_SEG(0x00011800800000C0ull)
+#define CVMX_L2C_SPAR0 \
+ CVMX_ADD_IO_SEG(0x0001180080000068ull)
+#define CVMX_L2C_SPAR1 \
+ CVMX_ADD_IO_SEG(0x0001180080000070ull)
+#define CVMX_L2C_SPAR2 \
+ CVMX_ADD_IO_SEG(0x0001180080000078ull)
+#define CVMX_L2C_SPAR3 \
+ CVMX_ADD_IO_SEG(0x0001180080000080ull)
+#define CVMX_L2C_SPAR4 \
+ CVMX_ADD_IO_SEG(0x0001180080000088ull)
+
+union cvmx_l2c_bst0 {
+ uint64_t u64;
+ struct cvmx_l2c_bst0_s {
+ uint64_t reserved_24_63:40;
+ uint64_t dtbnk:1;
+ uint64_t wlb_msk:4;
+ uint64_t dtcnt:13;
+ uint64_t dt:1;
+ uint64_t stin_msk:1;
+ uint64_t wlb_dat:4;
+ } s;
+ struct cvmx_l2c_bst0_cn30xx {
+ uint64_t reserved_23_63:41;
+ uint64_t wlb_msk:4;
+ uint64_t reserved_15_18:4;
+ uint64_t dtcnt:9;
+ uint64_t dt:1;
+ uint64_t reserved_4_4:1;
+ uint64_t wlb_dat:4;
+ } cn30xx;
+ struct cvmx_l2c_bst0_cn31xx {
+ uint64_t reserved_23_63:41;
+ uint64_t wlb_msk:4;
+ uint64_t reserved_16_18:3;
+ uint64_t dtcnt:10;
+ uint64_t dt:1;
+ uint64_t stin_msk:1;
+ uint64_t wlb_dat:4;
+ } cn31xx;
+ struct cvmx_l2c_bst0_cn38xx {
+ uint64_t reserved_19_63:45;
+ uint64_t dtcnt:13;
+ uint64_t dt:1;
+ uint64_t stin_msk:1;
+ uint64_t wlb_dat:4;
+ } cn38xx;
+ struct cvmx_l2c_bst0_cn38xx cn38xxp2;
+ struct cvmx_l2c_bst0_cn50xx {
+ uint64_t reserved_24_63:40;
+ uint64_t dtbnk:1;
+ uint64_t wlb_msk:4;
+ uint64_t reserved_16_18:3;
+ uint64_t dtcnt:10;
+ uint64_t dt:1;
+ uint64_t stin_msk:1;
+ uint64_t wlb_dat:4;
+ } cn50xx;
+ struct cvmx_l2c_bst0_cn50xx cn52xx;
+ struct cvmx_l2c_bst0_cn50xx cn52xxp1;
+ struct cvmx_l2c_bst0_s cn56xx;
+ struct cvmx_l2c_bst0_s cn56xxp1;
+ struct cvmx_l2c_bst0_s cn58xx;
+ struct cvmx_l2c_bst0_s cn58xxp1;
+};
+
+union cvmx_l2c_bst1 {
+ uint64_t u64;
+ struct cvmx_l2c_bst1_s {
+ uint64_t reserved_9_63:55;
+ uint64_t l2t:9;
+ } s;
+ struct cvmx_l2c_bst1_cn30xx {
+ uint64_t reserved_16_63:48;
+ uint64_t vwdf:4;
+ uint64_t lrf:2;
+ uint64_t vab_vwcf:1;
+ uint64_t reserved_5_8:4;
+ uint64_t l2t:5;
+ } cn30xx;
+ struct cvmx_l2c_bst1_cn30xx cn31xx;
+ struct cvmx_l2c_bst1_cn38xx {
+ uint64_t reserved_16_63:48;
+ uint64_t vwdf:4;
+ uint64_t lrf:2;
+ uint64_t vab_vwcf:1;
+ uint64_t l2t:9;
+ } cn38xx;
+ struct cvmx_l2c_bst1_cn38xx cn38xxp2;
+ struct cvmx_l2c_bst1_cn38xx cn50xx;
+ struct cvmx_l2c_bst1_cn52xx {
+ uint64_t reserved_19_63:45;
+ uint64_t plc2:1;
+ uint64_t plc1:1;
+ uint64_t plc0:1;
+ uint64_t vwdf:4;
+ uint64_t reserved_11_11:1;
+ uint64_t ilc:1;
+ uint64_t vab_vwcf:1;
+ uint64_t l2t:9;
+ } cn52xx;
+ struct cvmx_l2c_bst1_cn52xx cn52xxp1;
+ struct cvmx_l2c_bst1_cn56xx {
+ uint64_t reserved_24_63:40;
+ uint64_t plc2:1;
+ uint64_t plc1:1;
+ uint64_t plc0:1;
+ uint64_t ilc:1;
+ uint64_t vwdf1:4;
+ uint64_t vwdf0:4;
+ uint64_t vab_vwcf1:1;
+ uint64_t reserved_10_10:1;
+ uint64_t vab_vwcf0:1;
+ uint64_t l2t:9;
+ } cn56xx;
+ struct cvmx_l2c_bst1_cn56xx cn56xxp1;
+ struct cvmx_l2c_bst1_cn38xx cn58xx;
+ struct cvmx_l2c_bst1_cn38xx cn58xxp1;
+};
+
+union cvmx_l2c_bst2 {
+ uint64_t u64;
+ struct cvmx_l2c_bst2_s {
+ uint64_t reserved_16_63:48;
+ uint64_t mrb:4;
+ uint64_t reserved_4_11:8;
+ uint64_t ipcbst:1;
+ uint64_t picbst:1;
+ uint64_t xrdmsk:1;
+ uint64_t xrddat:1;
+ } s;
+ struct cvmx_l2c_bst2_cn30xx {
+ uint64_t reserved_16_63:48;
+ uint64_t mrb:4;
+ uint64_t rmdf:4;
+ uint64_t reserved_4_7:4;
+ uint64_t ipcbst:1;
+ uint64_t reserved_2_2:1;
+ uint64_t xrdmsk:1;
+ uint64_t xrddat:1;
+ } cn30xx;
+ struct cvmx_l2c_bst2_cn30xx cn31xx;
+ struct cvmx_l2c_bst2_cn38xx {
+ uint64_t reserved_16_63:48;
+ uint64_t mrb:4;
+ uint64_t rmdf:4;
+ uint64_t rhdf:4;
+ uint64_t ipcbst:1;
+ uint64_t picbst:1;
+ uint64_t xrdmsk:1;
+ uint64_t xrddat:1;
+ } cn38xx;
+ struct cvmx_l2c_bst2_cn38xx cn38xxp2;
+ struct cvmx_l2c_bst2_cn30xx cn50xx;
+ struct cvmx_l2c_bst2_cn30xx cn52xx;
+ struct cvmx_l2c_bst2_cn30xx cn52xxp1;
+ struct cvmx_l2c_bst2_cn56xx {
+ uint64_t reserved_16_63:48;
+ uint64_t mrb:4;
+ uint64_t rmdb:4;
+ uint64_t rhdb:4;
+ uint64_t ipcbst:1;
+ uint64_t picbst:1;
+ uint64_t xrdmsk:1;
+ uint64_t xrddat:1;
+ } cn56xx;
+ struct cvmx_l2c_bst2_cn56xx cn56xxp1;
+ struct cvmx_l2c_bst2_cn56xx cn58xx;
+ struct cvmx_l2c_bst2_cn56xx cn58xxp1;
+};
+
+union cvmx_l2c_cfg {
+ uint64_t u64;
+ struct cvmx_l2c_cfg_s {
+ uint64_t reserved_20_63:44;
+ uint64_t bstrun:1;
+ uint64_t lbist:1;
+ uint64_t xor_bank:1;
+ uint64_t dpres1:1;
+ uint64_t dpres0:1;
+ uint64_t dfill_dis:1;
+ uint64_t fpexp:4;
+ uint64_t fpempty:1;
+ uint64_t fpen:1;
+ uint64_t idxalias:1;
+ uint64_t mwf_crd:4;
+ uint64_t rsp_arb_mode:1;
+ uint64_t rfb_arb_mode:1;
+ uint64_t lrf_arb_mode:1;
+ } s;
+ struct cvmx_l2c_cfg_cn30xx {
+ uint64_t reserved_14_63:50;
+ uint64_t fpexp:4;
+ uint64_t fpempty:1;
+ uint64_t fpen:1;
+ uint64_t idxalias:1;
+ uint64_t mwf_crd:4;
+ uint64_t rsp_arb_mode:1;
+ uint64_t rfb_arb_mode:1;
+ uint64_t lrf_arb_mode:1;
+ } cn30xx;
+ struct cvmx_l2c_cfg_cn30xx cn31xx;
+ struct cvmx_l2c_cfg_cn30xx cn38xx;
+ struct cvmx_l2c_cfg_cn30xx cn38xxp2;
+ struct cvmx_l2c_cfg_cn50xx {
+ uint64_t reserved_20_63:44;
+ uint64_t bstrun:1;
+ uint64_t lbist:1;
+ uint64_t reserved_14_17:4;
+ uint64_t fpexp:4;
+ uint64_t fpempty:1;
+ uint64_t fpen:1;
+ uint64_t idxalias:1;
+ uint64_t mwf_crd:4;
+ uint64_t rsp_arb_mode:1;
+ uint64_t rfb_arb_mode:1;
+ uint64_t lrf_arb_mode:1;
+ } cn50xx;
+ struct cvmx_l2c_cfg_cn50xx cn52xx;
+ struct cvmx_l2c_cfg_cn50xx cn52xxp1;
+ struct cvmx_l2c_cfg_s cn56xx;
+ struct cvmx_l2c_cfg_s cn56xxp1;
+ struct cvmx_l2c_cfg_cn58xx {
+ uint64_t reserved_20_63:44;
+ uint64_t bstrun:1;
+ uint64_t lbist:1;
+ uint64_t reserved_15_17:3;
+ uint64_t dfill_dis:1;
+ uint64_t fpexp:4;
+ uint64_t fpempty:1;
+ uint64_t fpen:1;
+ uint64_t idxalias:1;
+ uint64_t mwf_crd:4;
+ uint64_t rsp_arb_mode:1;
+ uint64_t rfb_arb_mode:1;
+ uint64_t lrf_arb_mode:1;
+ } cn58xx;
+ struct cvmx_l2c_cfg_cn58xxp1 {
+ uint64_t reserved_15_63:49;
+ uint64_t dfill_dis:1;
+ uint64_t fpexp:4;
+ uint64_t fpempty:1;
+ uint64_t fpen:1;
+ uint64_t idxalias:1;
+ uint64_t mwf_crd:4;
+ uint64_t rsp_arb_mode:1;
+ uint64_t rfb_arb_mode:1;
+ uint64_t lrf_arb_mode:1;
+ } cn58xxp1;
+};
+
+union cvmx_l2c_dbg {
+ uint64_t u64;
+ struct cvmx_l2c_dbg_s {
+ uint64_t reserved_15_63:49;
+ uint64_t lfb_enum:4;
+ uint64_t lfb_dmp:1;
+ uint64_t ppnum:4;
+ uint64_t set:3;
+ uint64_t finv:1;
+ uint64_t l2d:1;
+ uint64_t l2t:1;
+ } s;
+ struct cvmx_l2c_dbg_cn30xx {
+ uint64_t reserved_13_63:51;
+ uint64_t lfb_enum:2;
+ uint64_t lfb_dmp:1;
+ uint64_t reserved_5_9:5;
+ uint64_t set:2;
+ uint64_t finv:1;
+ uint64_t l2d:1;
+ uint64_t l2t:1;
+ } cn30xx;
+ struct cvmx_l2c_dbg_cn31xx {
+ uint64_t reserved_14_63:50;
+ uint64_t lfb_enum:3;
+ uint64_t lfb_dmp:1;
+ uint64_t reserved_7_9:3;
+ uint64_t ppnum:1;
+ uint64_t reserved_5_5:1;
+ uint64_t set:2;
+ uint64_t finv:1;
+ uint64_t l2d:1;
+ uint64_t l2t:1;
+ } cn31xx;
+ struct cvmx_l2c_dbg_s cn38xx;
+ struct cvmx_l2c_dbg_s cn38xxp2;
+ struct cvmx_l2c_dbg_cn50xx {
+ uint64_t reserved_14_63:50;
+ uint64_t lfb_enum:3;
+ uint64_t lfb_dmp:1;
+ uint64_t reserved_7_9:3;
+ uint64_t ppnum:1;
+ uint64_t set:3;
+ uint64_t finv:1;
+ uint64_t l2d:1;
+ uint64_t l2t:1;
+ } cn50xx;
+ struct cvmx_l2c_dbg_cn52xx {
+ uint64_t reserved_14_63:50;
+ uint64_t lfb_enum:3;
+ uint64_t lfb_dmp:1;
+ uint64_t reserved_8_9:2;
+ uint64_t ppnum:2;
+ uint64_t set:3;
+ uint64_t finv:1;
+ uint64_t l2d:1;
+ uint64_t l2t:1;
+ } cn52xx;
+ struct cvmx_l2c_dbg_cn52xx cn52xxp1;
+ struct cvmx_l2c_dbg_s cn56xx;
+ struct cvmx_l2c_dbg_s cn56xxp1;
+ struct cvmx_l2c_dbg_s cn58xx;
+ struct cvmx_l2c_dbg_s cn58xxp1;
+};
+
+union cvmx_l2c_dut {
+ uint64_t u64;
+ struct cvmx_l2c_dut_s {
+ uint64_t reserved_32_63:32;
+ uint64_t dtena:1;
+ uint64_t reserved_30_30:1;
+ uint64_t dt_vld:1;
+ uint64_t dt_tag:29;
+ } s;
+ struct cvmx_l2c_dut_s cn30xx;
+ struct cvmx_l2c_dut_s cn31xx;
+ struct cvmx_l2c_dut_s cn38xx;
+ struct cvmx_l2c_dut_s cn38xxp2;
+ struct cvmx_l2c_dut_s cn50xx;
+ struct cvmx_l2c_dut_s cn52xx;
+ struct cvmx_l2c_dut_s cn52xxp1;
+ struct cvmx_l2c_dut_s cn56xx;
+ struct cvmx_l2c_dut_s cn56xxp1;
+ struct cvmx_l2c_dut_s cn58xx;
+ struct cvmx_l2c_dut_s cn58xxp1;
+};
+
+union cvmx_l2c_grpwrr0 {
+ uint64_t u64;
+ struct cvmx_l2c_grpwrr0_s {
+ uint64_t plc1rmsk:32;
+ uint64_t plc0rmsk:32;
+ } s;
+ struct cvmx_l2c_grpwrr0_s cn52xx;
+ struct cvmx_l2c_grpwrr0_s cn52xxp1;
+ struct cvmx_l2c_grpwrr0_s cn56xx;
+ struct cvmx_l2c_grpwrr0_s cn56xxp1;
+};
+
+union cvmx_l2c_grpwrr1 {
+ uint64_t u64;
+ struct cvmx_l2c_grpwrr1_s {
+ uint64_t ilcrmsk:32;
+ uint64_t plc2rmsk:32;
+ } s;
+ struct cvmx_l2c_grpwrr1_s cn52xx;
+ struct cvmx_l2c_grpwrr1_s cn52xxp1;
+ struct cvmx_l2c_grpwrr1_s cn56xx;
+ struct cvmx_l2c_grpwrr1_s cn56xxp1;
+};
+
+union cvmx_l2c_int_en {
+ uint64_t u64;
+ struct cvmx_l2c_int_en_s {
+ uint64_t reserved_9_63:55;
+ uint64_t lck2ena:1;
+ uint64_t lckena:1;
+ uint64_t l2ddeden:1;
+ uint64_t l2dsecen:1;
+ uint64_t l2tdeden:1;
+ uint64_t l2tsecen:1;
+ uint64_t oob3en:1;
+ uint64_t oob2en:1;
+ uint64_t oob1en:1;
+ } s;
+ struct cvmx_l2c_int_en_s cn52xx;
+ struct cvmx_l2c_int_en_s cn52xxp1;
+ struct cvmx_l2c_int_en_s cn56xx;
+ struct cvmx_l2c_int_en_s cn56xxp1;
+};
+
+union cvmx_l2c_int_stat {
+ uint64_t u64;
+ struct cvmx_l2c_int_stat_s {
+ uint64_t reserved_9_63:55;
+ uint64_t lck2:1;
+ uint64_t lck:1;
+ uint64_t l2dded:1;
+ uint64_t l2dsec:1;
+ uint64_t l2tded:1;
+ uint64_t l2tsec:1;
+ uint64_t oob3:1;
+ uint64_t oob2:1;
+ uint64_t oob1:1;
+ } s;
+ struct cvmx_l2c_int_stat_s cn52xx;
+ struct cvmx_l2c_int_stat_s cn52xxp1;
+ struct cvmx_l2c_int_stat_s cn56xx;
+ struct cvmx_l2c_int_stat_s cn56xxp1;
+};
+
+union cvmx_l2c_lckbase {
+ uint64_t u64;
+ struct cvmx_l2c_lckbase_s {
+ uint64_t reserved_31_63:33;
+ uint64_t lck_base:27;
+ uint64_t reserved_1_3:3;
+ uint64_t lck_ena:1;
+ } s;
+ struct cvmx_l2c_lckbase_s cn30xx;
+ struct cvmx_l2c_lckbase_s cn31xx;
+ struct cvmx_l2c_lckbase_s cn38xx;
+ struct cvmx_l2c_lckbase_s cn38xxp2;
+ struct cvmx_l2c_lckbase_s cn50xx;
+ struct cvmx_l2c_lckbase_s cn52xx;
+ struct cvmx_l2c_lckbase_s cn52xxp1;
+ struct cvmx_l2c_lckbase_s cn56xx;
+ struct cvmx_l2c_lckbase_s cn56xxp1;
+ struct cvmx_l2c_lckbase_s cn58xx;
+ struct cvmx_l2c_lckbase_s cn58xxp1;
+};
+
+union cvmx_l2c_lckoff {
+ uint64_t u64;
+ struct cvmx_l2c_lckoff_s {
+ uint64_t reserved_10_63:54;
+ uint64_t lck_offset:10;
+ } s;
+ struct cvmx_l2c_lckoff_s cn30xx;
+ struct cvmx_l2c_lckoff_s cn31xx;
+ struct cvmx_l2c_lckoff_s cn38xx;
+ struct cvmx_l2c_lckoff_s cn38xxp2;
+ struct cvmx_l2c_lckoff_s cn50xx;
+ struct cvmx_l2c_lckoff_s cn52xx;
+ struct cvmx_l2c_lckoff_s cn52xxp1;
+ struct cvmx_l2c_lckoff_s cn56xx;
+ struct cvmx_l2c_lckoff_s cn56xxp1;
+ struct cvmx_l2c_lckoff_s cn58xx;
+ struct cvmx_l2c_lckoff_s cn58xxp1;
+};
+
+union cvmx_l2c_lfb0 {
+ uint64_t u64;
+ struct cvmx_l2c_lfb0_s {
+ uint64_t reserved_32_63:32;
+ uint64_t stcpnd:1;
+ uint64_t stpnd:1;
+ uint64_t stinv:1;
+ uint64_t stcfl:1;
+ uint64_t vam:1;
+ uint64_t inxt:4;
+ uint64_t itl:1;
+ uint64_t ihd:1;
+ uint64_t set:3;
+ uint64_t vabnum:4;
+ uint64_t sid:9;
+ uint64_t cmd:4;
+ uint64_t vld:1;
+ } s;
+ struct cvmx_l2c_lfb0_cn30xx {
+ uint64_t reserved_32_63:32;
+ uint64_t stcpnd:1;
+ uint64_t stpnd:1;
+ uint64_t stinv:1;
+ uint64_t stcfl:1;
+ uint64_t vam:1;
+ uint64_t reserved_25_26:2;
+ uint64_t inxt:2;
+ uint64_t itl:1;
+ uint64_t ihd:1;
+ uint64_t reserved_20_20:1;
+ uint64_t set:2;
+ uint64_t reserved_16_17:2;
+ uint64_t vabnum:2;
+ uint64_t sid:9;
+ uint64_t cmd:4;
+ uint64_t vld:1;
+ } cn30xx;
+ struct cvmx_l2c_lfb0_cn31xx {
+ uint64_t reserved_32_63:32;
+ uint64_t stcpnd:1;
+ uint64_t stpnd:1;
+ uint64_t stinv:1;
+ uint64_t stcfl:1;
+ uint64_t vam:1;
+ uint64_t reserved_26_26:1;
+ uint64_t inxt:3;
+ uint64_t itl:1;
+ uint64_t ihd:1;
+ uint64_t reserved_20_20:1;
+ uint64_t set:2;
+ uint64_t reserved_17_17:1;
+ uint64_t vabnum:3;
+ uint64_t sid:9;
+ uint64_t cmd:4;
+ uint64_t vld:1;
+ } cn31xx;
+ struct cvmx_l2c_lfb0_s cn38xx;
+ struct cvmx_l2c_lfb0_s cn38xxp2;
+ struct cvmx_l2c_lfb0_cn50xx {
+ uint64_t reserved_32_63:32;
+ uint64_t stcpnd:1;
+ uint64_t stpnd:1;
+ uint64_t stinv:1;
+ uint64_t stcfl:1;
+ uint64_t vam:1;
+ uint64_t reserved_26_26:1;
+ uint64_t inxt:3;
+ uint64_t itl:1;
+ uint64_t ihd:1;
+ uint64_t set:3;
+ uint64_t reserved_17_17:1;
+ uint64_t vabnum:3;
+ uint64_t sid:9;
+ uint64_t cmd:4;
+ uint64_t vld:1;
+ } cn50xx;
+ struct cvmx_l2c_lfb0_cn50xx cn52xx;
+ struct cvmx_l2c_lfb0_cn50xx cn52xxp1;
+ struct cvmx_l2c_lfb0_s cn56xx;
+ struct cvmx_l2c_lfb0_s cn56xxp1;
+ struct cvmx_l2c_lfb0_s cn58xx;
+ struct cvmx_l2c_lfb0_s cn58xxp1;
+};
+
+union cvmx_l2c_lfb1 {
+ uint64_t u64;
+ struct cvmx_l2c_lfb1_s {
+ uint64_t reserved_19_63:45;
+ uint64_t dsgoing:1;
+ uint64_t bid:2;
+ uint64_t wtrsp:1;
+ uint64_t wtdw:1;
+ uint64_t wtdq:1;
+ uint64_t wtwhp:1;
+ uint64_t wtwhf:1;
+ uint64_t wtwrm:1;
+ uint64_t wtstm:1;
+ uint64_t wtrda:1;
+ uint64_t wtstdt:1;
+ uint64_t wtstrsp:1;
+ uint64_t wtstrsc:1;
+ uint64_t wtvtm:1;
+ uint64_t wtmfl:1;
+ uint64_t prbrty:1;
+ uint64_t wtprb:1;
+ uint64_t vld:1;
+ } s;
+ struct cvmx_l2c_lfb1_s cn30xx;
+ struct cvmx_l2c_lfb1_s cn31xx;
+ struct cvmx_l2c_lfb1_s cn38xx;
+ struct cvmx_l2c_lfb1_s cn38xxp2;
+ struct cvmx_l2c_lfb1_s cn50xx;
+ struct cvmx_l2c_lfb1_s cn52xx;
+ struct cvmx_l2c_lfb1_s cn52xxp1;
+ struct cvmx_l2c_lfb1_s cn56xx;
+ struct cvmx_l2c_lfb1_s cn56xxp1;
+ struct cvmx_l2c_lfb1_s cn58xx;
+ struct cvmx_l2c_lfb1_s cn58xxp1;
+};
+
+union cvmx_l2c_lfb2 {
+ uint64_t u64;
+ struct cvmx_l2c_lfb2_s {
+ uint64_t reserved_0_63:64;
+ } s;
+ struct cvmx_l2c_lfb2_cn30xx {
+ uint64_t reserved_27_63:37;
+ uint64_t lfb_tag:19;
+ uint64_t lfb_idx:8;
+ } cn30xx;
+ struct cvmx_l2c_lfb2_cn31xx {
+ uint64_t reserved_27_63:37;
+ uint64_t lfb_tag:17;
+ uint64_t lfb_idx:10;
+ } cn31xx;
+ struct cvmx_l2c_lfb2_cn31xx cn38xx;
+ struct cvmx_l2c_lfb2_cn31xx cn38xxp2;
+ struct cvmx_l2c_lfb2_cn50xx {
+ uint64_t reserved_27_63:37;
+ uint64_t lfb_tag:20;
+ uint64_t lfb_idx:7;
+ } cn50xx;
+ struct cvmx_l2c_lfb2_cn52xx {
+ uint64_t reserved_27_63:37;
+ uint64_t lfb_tag:18;
+ uint64_t lfb_idx:9;
+ } cn52xx;
+ struct cvmx_l2c_lfb2_cn52xx cn52xxp1;
+ struct cvmx_l2c_lfb2_cn56xx {
+ uint64_t reserved_27_63:37;
+ uint64_t lfb_tag:16;
+ uint64_t lfb_idx:11;
+ } cn56xx;
+ struct cvmx_l2c_lfb2_cn56xx cn56xxp1;
+ struct cvmx_l2c_lfb2_cn56xx cn58xx;
+ struct cvmx_l2c_lfb2_cn56xx cn58xxp1;
+};
+
+union cvmx_l2c_lfb3 {
+ uint64_t u64;
+ struct cvmx_l2c_lfb3_s {
+ uint64_t reserved_5_63:59;
+ uint64_t stpartdis:1;
+ uint64_t lfb_hwm:4;
+ } s;
+ struct cvmx_l2c_lfb3_cn30xx {
+ uint64_t reserved_5_63:59;
+ uint64_t stpartdis:1;
+ uint64_t reserved_2_3:2;
+ uint64_t lfb_hwm:2;
+ } cn30xx;
+ struct cvmx_l2c_lfb3_cn31xx {
+ uint64_t reserved_5_63:59;
+ uint64_t stpartdis:1;
+ uint64_t reserved_3_3:1;
+ uint64_t lfb_hwm:3;
+ } cn31xx;
+ struct cvmx_l2c_lfb3_s cn38xx;
+ struct cvmx_l2c_lfb3_s cn38xxp2;
+ struct cvmx_l2c_lfb3_cn31xx cn50xx;
+ struct cvmx_l2c_lfb3_cn31xx cn52xx;
+ struct cvmx_l2c_lfb3_cn31xx cn52xxp1;
+ struct cvmx_l2c_lfb3_s cn56xx;
+ struct cvmx_l2c_lfb3_s cn56xxp1;
+ struct cvmx_l2c_lfb3_s cn58xx;
+ struct cvmx_l2c_lfb3_s cn58xxp1;
+};
+
+union cvmx_l2c_oob {
+ uint64_t u64;
+ struct cvmx_l2c_oob_s {
+ uint64_t reserved_2_63:62;
+ uint64_t dwbena:1;
+ uint64_t stena:1;
+ } s;
+ struct cvmx_l2c_oob_s cn52xx;
+ struct cvmx_l2c_oob_s cn52xxp1;
+ struct cvmx_l2c_oob_s cn56xx;
+ struct cvmx_l2c_oob_s cn56xxp1;
+};
+
+union cvmx_l2c_oob1 {
+ uint64_t u64;
+ struct cvmx_l2c_oob1_s {
+ uint64_t fadr:27;
+ uint64_t fsrc:1;
+ uint64_t reserved_34_35:2;
+ uint64_t sadr:14;
+ uint64_t reserved_14_19:6;
+ uint64_t size:14;
+ } s;
+ struct cvmx_l2c_oob1_s cn52xx;
+ struct cvmx_l2c_oob1_s cn52xxp1;
+ struct cvmx_l2c_oob1_s cn56xx;
+ struct cvmx_l2c_oob1_s cn56xxp1;
+};
+
+union cvmx_l2c_oob2 {
+ uint64_t u64;
+ struct cvmx_l2c_oob2_s {
+ uint64_t fadr:27;
+ uint64_t fsrc:1;
+ uint64_t reserved_34_35:2;
+ uint64_t sadr:14;
+ uint64_t reserved_14_19:6;
+ uint64_t size:14;
+ } s;
+ struct cvmx_l2c_oob2_s cn52xx;
+ struct cvmx_l2c_oob2_s cn52xxp1;
+ struct cvmx_l2c_oob2_s cn56xx;
+ struct cvmx_l2c_oob2_s cn56xxp1;
+};
+
+union cvmx_l2c_oob3 {
+ uint64_t u64;
+ struct cvmx_l2c_oob3_s {
+ uint64_t fadr:27;
+ uint64_t fsrc:1;
+ uint64_t reserved_34_35:2;
+ uint64_t sadr:14;
+ uint64_t reserved_14_19:6;
+ uint64_t size:14;
+ } s;
+ struct cvmx_l2c_oob3_s cn52xx;
+ struct cvmx_l2c_oob3_s cn52xxp1;
+ struct cvmx_l2c_oob3_s cn56xx;
+ struct cvmx_l2c_oob3_s cn56xxp1;
+};
+
+union cvmx_l2c_pfcx {
+ uint64_t u64;
+ struct cvmx_l2c_pfcx_s {
+ uint64_t reserved_36_63:28;
+ uint64_t pfcnt0:36;
+ } s;
+ struct cvmx_l2c_pfcx_s cn30xx;
+ struct cvmx_l2c_pfcx_s cn31xx;
+ struct cvmx_l2c_pfcx_s cn38xx;
+ struct cvmx_l2c_pfcx_s cn38xxp2;
+ struct cvmx_l2c_pfcx_s cn50xx;
+ struct cvmx_l2c_pfcx_s cn52xx;
+ struct cvmx_l2c_pfcx_s cn52xxp1;
+ struct cvmx_l2c_pfcx_s cn56xx;
+ struct cvmx_l2c_pfcx_s cn56xxp1;
+ struct cvmx_l2c_pfcx_s cn58xx;
+ struct cvmx_l2c_pfcx_s cn58xxp1;
+};
+
+union cvmx_l2c_pfctl {
+ uint64_t u64;
+ struct cvmx_l2c_pfctl_s {
+ uint64_t reserved_36_63:28;
+ uint64_t cnt3rdclr:1;
+ uint64_t cnt2rdclr:1;
+ uint64_t cnt1rdclr:1;
+ uint64_t cnt0rdclr:1;
+ uint64_t cnt3ena:1;
+ uint64_t cnt3clr:1;
+ uint64_t cnt3sel:6;
+ uint64_t cnt2ena:1;
+ uint64_t cnt2clr:1;
+ uint64_t cnt2sel:6;
+ uint64_t cnt1ena:1;
+ uint64_t cnt1clr:1;
+ uint64_t cnt1sel:6;
+ uint64_t cnt0ena:1;
+ uint64_t cnt0clr:1;
+ uint64_t cnt0sel:6;
+ } s;
+ struct cvmx_l2c_pfctl_s cn30xx;
+ struct cvmx_l2c_pfctl_s cn31xx;
+ struct cvmx_l2c_pfctl_s cn38xx;
+ struct cvmx_l2c_pfctl_s cn38xxp2;
+ struct cvmx_l2c_pfctl_s cn50xx;
+ struct cvmx_l2c_pfctl_s cn52xx;
+ struct cvmx_l2c_pfctl_s cn52xxp1;
+ struct cvmx_l2c_pfctl_s cn56xx;
+ struct cvmx_l2c_pfctl_s cn56xxp1;
+ struct cvmx_l2c_pfctl_s cn58xx;
+ struct cvmx_l2c_pfctl_s cn58xxp1;
+};
+
+union cvmx_l2c_ppgrp {
+ uint64_t u64;
+ struct cvmx_l2c_ppgrp_s {
+ uint64_t reserved_24_63:40;
+ uint64_t pp11grp:2;
+ uint64_t pp10grp:2;
+ uint64_t pp9grp:2;
+ uint64_t pp8grp:2;
+ uint64_t pp7grp:2;
+ uint64_t pp6grp:2;
+ uint64_t pp5grp:2;
+ uint64_t pp4grp:2;
+ uint64_t pp3grp:2;
+ uint64_t pp2grp:2;
+ uint64_t pp1grp:2;
+ uint64_t pp0grp:2;
+ } s;
+ struct cvmx_l2c_ppgrp_cn52xx {
+ uint64_t reserved_8_63:56;
+ uint64_t pp3grp:2;
+ uint64_t pp2grp:2;
+ uint64_t pp1grp:2;
+ uint64_t pp0grp:2;
+ } cn52xx;
+ struct cvmx_l2c_ppgrp_cn52xx cn52xxp1;
+ struct cvmx_l2c_ppgrp_s cn56xx;
+ struct cvmx_l2c_ppgrp_s cn56xxp1;
+};
+
+union cvmx_l2c_spar0 {
+ uint64_t u64;
+ struct cvmx_l2c_spar0_s {
+ uint64_t reserved_32_63:32;
+ uint64_t umsk3:8;
+ uint64_t umsk2:8;
+ uint64_t umsk1:8;
+ uint64_t umsk0:8;
+ } s;
+ struct cvmx_l2c_spar0_cn30xx {
+ uint64_t reserved_4_63:60;
+ uint64_t umsk0:4;
+ } cn30xx;
+ struct cvmx_l2c_spar0_cn31xx {
+ uint64_t reserved_12_63:52;
+ uint64_t umsk1:4;
+ uint64_t reserved_4_7:4;
+ uint64_t umsk0:4;
+ } cn31xx;
+ struct cvmx_l2c_spar0_s cn38xx;
+ struct cvmx_l2c_spar0_s cn38xxp2;
+ struct cvmx_l2c_spar0_cn50xx {
+ uint64_t reserved_16_63:48;
+ uint64_t umsk1:8;
+ uint64_t umsk0:8;
+ } cn50xx;
+ struct cvmx_l2c_spar0_s cn52xx;
+ struct cvmx_l2c_spar0_s cn52xxp1;
+ struct cvmx_l2c_spar0_s cn56xx;
+ struct cvmx_l2c_spar0_s cn56xxp1;
+ struct cvmx_l2c_spar0_s cn58xx;
+ struct cvmx_l2c_spar0_s cn58xxp1;
+};
+
+union cvmx_l2c_spar1 {
+ uint64_t u64;
+ struct cvmx_l2c_spar1_s {
+ uint64_t reserved_32_63:32;
+ uint64_t umsk7:8;
+ uint64_t umsk6:8;
+ uint64_t umsk5:8;
+ uint64_t umsk4:8;
+ } s;
+ struct cvmx_l2c_spar1_s cn38xx;
+ struct cvmx_l2c_spar1_s cn38xxp2;
+ struct cvmx_l2c_spar1_s cn56xx;
+ struct cvmx_l2c_spar1_s cn56xxp1;
+ struct cvmx_l2c_spar1_s cn58xx;
+ struct cvmx_l2c_spar1_s cn58xxp1;
+};
+
+union cvmx_l2c_spar2 {
+ uint64_t u64;
+ struct cvmx_l2c_spar2_s {
+ uint64_t reserved_32_63:32;
+ uint64_t umsk11:8;
+ uint64_t umsk10:8;
+ uint64_t umsk9:8;
+ uint64_t umsk8:8;
+ } s;
+ struct cvmx_l2c_spar2_s cn38xx;
+ struct cvmx_l2c_spar2_s cn38xxp2;
+ struct cvmx_l2c_spar2_s cn56xx;
+ struct cvmx_l2c_spar2_s cn56xxp1;
+ struct cvmx_l2c_spar2_s cn58xx;
+ struct cvmx_l2c_spar2_s cn58xxp1;
+};
+
+union cvmx_l2c_spar3 {
+ uint64_t u64;
+ struct cvmx_l2c_spar3_s {
+ uint64_t reserved_32_63:32;
+ uint64_t umsk15:8;
+ uint64_t umsk14:8;
+ uint64_t umsk13:8;
+ uint64_t umsk12:8;
+ } s;
+ struct cvmx_l2c_spar3_s cn38xx;
+ struct cvmx_l2c_spar3_s cn38xxp2;
+ struct cvmx_l2c_spar3_s cn58xx;
+ struct cvmx_l2c_spar3_s cn58xxp1;
+};
+
+union cvmx_l2c_spar4 {
+ uint64_t u64;
+ struct cvmx_l2c_spar4_s {
+ uint64_t reserved_8_63:56;
+ uint64_t umskiob:8;
+ } s;
+ struct cvmx_l2c_spar4_cn30xx {
+ uint64_t reserved_4_63:60;
+ uint64_t umskiob:4;
+ } cn30xx;
+ struct cvmx_l2c_spar4_cn30xx cn31xx;
+ struct cvmx_l2c_spar4_s cn38xx;
+ struct cvmx_l2c_spar4_s cn38xxp2;
+ struct cvmx_l2c_spar4_s cn50xx;
+ struct cvmx_l2c_spar4_s cn52xx;
+ struct cvmx_l2c_spar4_s cn52xxp1;
+ struct cvmx_l2c_spar4_s cn56xx;
+ struct cvmx_l2c_spar4_s cn56xxp1;
+ struct cvmx_l2c_spar4_s cn58xx;
+ struct cvmx_l2c_spar4_s cn58xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-l2c.h b/arch/mips/include/asm/octeon/cvmx-l2c.h
new file mode 100644
index 0000000..2a8c090
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-l2c.h
@@ -0,0 +1,325 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ *
+ * Interface to the Level 2 Cache (L2C) control, measurement, and debugging
+ * facilities.
+ */
+
+#ifndef __CVMX_L2C_H__
+#define __CVMX_L2C_H__
+
+/* Deprecated macro, use function */
+#define CVMX_L2_ASSOC cvmx_l2c_get_num_assoc()
+
+/* Deprecated macro, use function */
+#define CVMX_L2_SET_BITS cvmx_l2c_get_set_bits()
+
+/* Deprecated macro, use function */
+#define CVMX_L2_SETS cvmx_l2c_get_num_sets()
+
+#define CVMX_L2C_IDX_ADDR_SHIFT 7 /* based on 128 byte cache line size */
+#define CVMX_L2C_IDX_MASK (cvmx_l2c_get_num_sets() - 1)
+
+/* Defines for index aliasing computations */
+#define CVMX_L2C_TAG_ADDR_ALIAS_SHIFT \
+ (CVMX_L2C_IDX_ADDR_SHIFT + cvmx_l2c_get_set_bits())
+
+#define CVMX_L2C_ALIAS_MASK \
+ (CVMX_L2C_IDX_MASK << CVMX_L2C_TAG_ADDR_ALIAS_SHIFT)
+
+union cvmx_l2c_tag {
+ uint64_t u64;
+ struct {
+ uint64_t reserved:28;
+ uint64_t V:1; /* Line valid */
+ uint64_t D:1; /* Line dirty */
+ uint64_t L:1; /* Line locked */
+ uint64_t U:1; /* Use, LRU eviction */
+ uint64_t addr:32; /* Phys mem (not all bits valid) */
+ } s;
+};
+
+ /* L2C Performance Counter events. */
+enum cvmx_l2c_event {
+ CVMX_L2C_EVENT_CYCLES = 0,
+ CVMX_L2C_EVENT_INSTRUCTION_MISS = 1,
+ CVMX_L2C_EVENT_INSTRUCTION_HIT = 2,
+ CVMX_L2C_EVENT_DATA_MISS = 3,
+ CVMX_L2C_EVENT_DATA_HIT = 4,
+ CVMX_L2C_EVENT_MISS = 5,
+ CVMX_L2C_EVENT_HIT = 6,
+ CVMX_L2C_EVENT_VICTIM_HIT = 7,
+ CVMX_L2C_EVENT_INDEX_CONFLICT = 8,
+ CVMX_L2C_EVENT_TAG_PROBE = 9,
+ CVMX_L2C_EVENT_TAG_UPDATE = 10,
+ CVMX_L2C_EVENT_TAG_COMPLETE = 11,
+ CVMX_L2C_EVENT_TAG_DIRTY = 12,
+ CVMX_L2C_EVENT_DATA_STORE_NOP = 13,
+ CVMX_L2C_EVENT_DATA_STORE_READ = 14,
+ CVMX_L2C_EVENT_DATA_STORE_WRITE = 15,
+ CVMX_L2C_EVENT_FILL_DATA_VALID = 16,
+ CVMX_L2C_EVENT_WRITE_REQUEST = 17,
+ CVMX_L2C_EVENT_READ_REQUEST = 18,
+ CVMX_L2C_EVENT_WRITE_DATA_VALID = 19,
+ CVMX_L2C_EVENT_XMC_NOP = 20,
+ CVMX_L2C_EVENT_XMC_LDT = 21,
+ CVMX_L2C_EVENT_XMC_LDI = 22,
+ CVMX_L2C_EVENT_XMC_LDD = 23,
+ CVMX_L2C_EVENT_XMC_STF = 24,
+ CVMX_L2C_EVENT_XMC_STT = 25,
+ CVMX_L2C_EVENT_XMC_STP = 26,
+ CVMX_L2C_EVENT_XMC_STC = 27,
+ CVMX_L2C_EVENT_XMC_DWB = 28,
+ CVMX_L2C_EVENT_XMC_PL2 = 29,
+ CVMX_L2C_EVENT_XMC_PSL1 = 30,
+ CVMX_L2C_EVENT_XMC_IOBLD = 31,
+ CVMX_L2C_EVENT_XMC_IOBST = 32,
+ CVMX_L2C_EVENT_XMC_IOBDMA = 33,
+ CVMX_L2C_EVENT_XMC_IOBRSP = 34,
+ CVMX_L2C_EVENT_XMC_BUS_VALID = 35,
+ CVMX_L2C_EVENT_XMC_MEM_DATA = 36,
+ CVMX_L2C_EVENT_XMC_REFL_DATA = 37,
+ CVMX_L2C_EVENT_XMC_IOBRSP_DATA = 38,
+ CVMX_L2C_EVENT_RSC_NOP = 39,
+ CVMX_L2C_EVENT_RSC_STDN = 40,
+ CVMX_L2C_EVENT_RSC_FILL = 41,
+ CVMX_L2C_EVENT_RSC_REFL = 42,
+ CVMX_L2C_EVENT_RSC_STIN = 43,
+ CVMX_L2C_EVENT_RSC_SCIN = 44,
+ CVMX_L2C_EVENT_RSC_SCFL = 45,
+ CVMX_L2C_EVENT_RSC_SCDN = 46,
+ CVMX_L2C_EVENT_RSC_DATA_VALID = 47,
+ CVMX_L2C_EVENT_RSC_VALID_FILL = 48,
+ CVMX_L2C_EVENT_RSC_VALID_STRSP = 49,
+ CVMX_L2C_EVENT_RSC_VALID_REFL = 50,
+ CVMX_L2C_EVENT_LRF_REQ = 51,
+ CVMX_L2C_EVENT_DT_RD_ALLOC = 52,
+ CVMX_L2C_EVENT_DT_WR_INVAL = 53
+};
+
+/**
+ * Configure one of the four L2 Cache performance counters to capture event
+ * occurences.
+ *
+ * @counter: The counter to configure. Range 0..3.
+ * @event: The type of L2 Cache event occurrence to count.
+ * @clear_on_read: When asserted, any read of the performance counter
+ * clears the counter.
+ *
+ * The routine does not clear the counter.
+ */
+void cvmx_l2c_config_perf(uint32_t counter,
+ enum cvmx_l2c_event event, uint32_t clear_on_read);
+/**
+ * Read the given L2 Cache performance counter. The counter must be configured
+ * before reading, but this routine does not enforce this requirement.
+ *
+ * @counter: The counter to configure. Range 0..3.
+ *
+ * Returns The current counter value.
+ */
+uint64_t cvmx_l2c_read_perf(uint32_t counter);
+
+/**
+ * Return the L2 Cache way partitioning for a given core.
+ *
+ * @core: The core processor of interest.
+ *
+ * Returns The mask specifying the partitioning. 0 bits in mask indicates
+ * the cache 'ways' that a core can evict from.
+ * -1 on error
+ */
+int cvmx_l2c_get_core_way_partition(uint32_t core);
+
+/**
+ * Partitions the L2 cache for a core
+ *
+ * @core: The core that the partitioning applies to.
+ *
+ * @mask: The partitioning of the ways expressed as a binary mask. A 0
+ * bit allows the core to evict cache lines from a way, while a
+ * 1 bit blocks the core from evicting any lines from that
+ * way. There must be at least one allowed way (0 bit) in the
+ * mask.
+ *
+ * If any ways are blocked for all cores and the HW blocks, then those
+ * ways will never have any cache lines evicted from them. All cores
+ * and the hardware blocks are free to read from all ways regardless
+ * of the partitioning.
+ */
+int cvmx_l2c_set_core_way_partition(uint32_t core, uint32_t mask);
+
+/**
+ * Return the L2 Cache way partitioning for the hw blocks.
+ *
+ * Returns The mask specifying the reserved way. 0 bits in mask indicates
+ * the cache 'ways' that a core can evict from.
+ * -1 on error
+ */
+int cvmx_l2c_get_hw_way_partition(void);
+
+/**
+ * Partitions the L2 cache for the hardware blocks.
+ *
+ * @mask: The partitioning of the ways expressed as a binary mask. A 0
+ * bit allows the core to evict cache lines from a way, while a
+ * 1 bit blocks the core from evicting any lines from that
+ * way. There must be at least one allowed way (0 bit) in the
+ * mask.
+ *
+ * If any ways are blocked for all cores and the HW blocks, then those
+ * ways will never have any cache lines evicted from them. All cores
+ * and the hardware blocks are free to read from all ways regardless
+ * of the partitioning.
+ */
+int cvmx_l2c_set_hw_way_partition(uint32_t mask);
+
+/**
+ * Locks a line in the L2 cache at the specified physical address
+ *
+ * @addr: physical address of line to lock
+ *
+ * Returns 0 on success,
+ * 1 if line not locked.
+ */
+int cvmx_l2c_lock_line(uint64_t addr);
+
+/**
+ * Locks a specified memory region in the L2 cache.
+ *
+ * Note that if not all lines can be locked, that means that all
+ * but one of the ways (associations) available to the locking
+ * core are locked. Having only 1 association available for
+ * normal caching may have a significant adverse affect on performance.
+ * Care should be taken to ensure that enough of the L2 cache is left
+ * unlocked to allow for normal caching of DRAM.
+ *
+ * @start: Physical address of the start of the region to lock
+ * @len: Length (in bytes) of region to lock
+ *
+ * Returns Number of requested lines that where not locked.
+ * 0 on success (all locked)
+ */
+int cvmx_l2c_lock_mem_region(uint64_t start, uint64_t len);
+
+/**
+ * Unlock and flush a cache line from the L2 cache.
+ * IMPORTANT: Must only be run by one core at a time due to use
+ * of L2C debug features.
+ * Note that this function will flush a matching but unlocked cache line.
+ * (If address is not in L2, no lines are flushed.)
+ *
+ * @address: Physical address to unlock
+ *
+ * Returns 0: line not unlocked
+ * 1: line unlocked
+ */
+int cvmx_l2c_unlock_line(uint64_t address);
+
+/**
+ * Unlocks a region of memory that is locked in the L2 cache
+ *
+ * @start: start physical address
+ * @len: length (in bytes) to unlock
+ *
+ * Returns Number of locked lines that the call unlocked
+ */
+int cvmx_l2c_unlock_mem_region(uint64_t start, uint64_t len);
+
+/**
+ * Read the L2 controller tag for a given location in L2
+ *
+ * @association:
+ * Which association to read line from
+ * @index: Which way to read from.
+ *
+ * Returns l2c tag structure for line requested.
+ */
+union cvmx_l2c_tag cvmx_l2c_get_tag(uint32_t association, uint32_t index);
+
+/* Wrapper around deprecated old function name */
+static inline union cvmx_l2c_tag cvmx_get_l2c_tag(uint32_t association,
+ uint32_t index)
+{
+ return cvmx_l2c_get_tag(association, index);
+}
+
+/**
+ * Returns the cache index for a given physical address
+ *
+ * @addr: physical address
+ *
+ * Returns L2 cache index
+ */
+uint32_t cvmx_l2c_address_to_index(uint64_t addr);
+
+/**
+ * Flushes (and unlocks) the entire L2 cache.
+ * IMPORTANT: Must only be run by one core at a time due to use
+ * of L2C debug features.
+ */
+void cvmx_l2c_flush(void);
+
+/**
+ *
+ * Returns Returns the size of the L2 cache in bytes,
+ * -1 on error (unrecognized model)
+ */
+int cvmx_l2c_get_cache_size_bytes(void);
+
+/**
+ * Return the number of sets in the L2 Cache
+ *
+ * Returns
+ */
+int cvmx_l2c_get_num_sets(void);
+
+/**
+ * Return log base 2 of the number of sets in the L2 cache
+ * Returns
+ */
+int cvmx_l2c_get_set_bits(void);
+/**
+ * Return the number of associations in the L2 Cache
+ *
+ * Returns
+ */
+int cvmx_l2c_get_num_assoc(void);
+
+/**
+ * Flush a line from the L2 cache
+ * This should only be called from one core at a time, as this routine
+ * sets the core to the 'debug' core in order to flush the line.
+ *
+ * @assoc: Association (or way) to flush
+ * @index: Index to flush
+ */
+void cvmx_l2c_flush_line(uint32_t assoc, uint32_t index);
+
+#endif /* __CVMX_L2C_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-l2d-defs.h b/arch/mips/include/asm/octeon/cvmx-l2d-defs.h
new file mode 100644
index 0000000..d7102d4
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-l2d-defs.h
@@ -0,0 +1,369 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_L2D_DEFS_H__
+#define __CVMX_L2D_DEFS_H__
+
+#define CVMX_L2D_BST0 \
+ CVMX_ADD_IO_SEG(0x0001180080000780ull)
+#define CVMX_L2D_BST1 \
+ CVMX_ADD_IO_SEG(0x0001180080000788ull)
+#define CVMX_L2D_BST2 \
+ CVMX_ADD_IO_SEG(0x0001180080000790ull)
+#define CVMX_L2D_BST3 \
+ CVMX_ADD_IO_SEG(0x0001180080000798ull)
+#define CVMX_L2D_ERR \
+ CVMX_ADD_IO_SEG(0x0001180080000010ull)
+#define CVMX_L2D_FADR \
+ CVMX_ADD_IO_SEG(0x0001180080000018ull)
+#define CVMX_L2D_FSYN0 \
+ CVMX_ADD_IO_SEG(0x0001180080000020ull)
+#define CVMX_L2D_FSYN1 \
+ CVMX_ADD_IO_SEG(0x0001180080000028ull)
+#define CVMX_L2D_FUS0 \
+ CVMX_ADD_IO_SEG(0x00011800800007A0ull)
+#define CVMX_L2D_FUS1 \
+ CVMX_ADD_IO_SEG(0x00011800800007A8ull)
+#define CVMX_L2D_FUS2 \
+ CVMX_ADD_IO_SEG(0x00011800800007B0ull)
+#define CVMX_L2D_FUS3 \
+ CVMX_ADD_IO_SEG(0x00011800800007B8ull)
+
+union cvmx_l2d_bst0 {
+ uint64_t u64;
+ struct cvmx_l2d_bst0_s {
+ uint64_t reserved_35_63:29;
+ uint64_t ftl:1;
+ uint64_t q0stat:34;
+ } s;
+ struct cvmx_l2d_bst0_s cn30xx;
+ struct cvmx_l2d_bst0_s cn31xx;
+ struct cvmx_l2d_bst0_s cn38xx;
+ struct cvmx_l2d_bst0_s cn38xxp2;
+ struct cvmx_l2d_bst0_s cn50xx;
+ struct cvmx_l2d_bst0_s cn52xx;
+ struct cvmx_l2d_bst0_s cn52xxp1;
+ struct cvmx_l2d_bst0_s cn56xx;
+ struct cvmx_l2d_bst0_s cn56xxp1;
+ struct cvmx_l2d_bst0_s cn58xx;
+ struct cvmx_l2d_bst0_s cn58xxp1;
+};
+
+union cvmx_l2d_bst1 {
+ uint64_t u64;
+ struct cvmx_l2d_bst1_s {
+ uint64_t reserved_34_63:30;
+ uint64_t q1stat:34;
+ } s;
+ struct cvmx_l2d_bst1_s cn30xx;
+ struct cvmx_l2d_bst1_s cn31xx;
+ struct cvmx_l2d_bst1_s cn38xx;
+ struct cvmx_l2d_bst1_s cn38xxp2;
+ struct cvmx_l2d_bst1_s cn50xx;
+ struct cvmx_l2d_bst1_s cn52xx;
+ struct cvmx_l2d_bst1_s cn52xxp1;
+ struct cvmx_l2d_bst1_s cn56xx;
+ struct cvmx_l2d_bst1_s cn56xxp1;
+ struct cvmx_l2d_bst1_s cn58xx;
+ struct cvmx_l2d_bst1_s cn58xxp1;
+};
+
+union cvmx_l2d_bst2 {
+ uint64_t u64;
+ struct cvmx_l2d_bst2_s {
+ uint64_t reserved_34_63:30;
+ uint64_t q2stat:34;
+ } s;
+ struct cvmx_l2d_bst2_s cn30xx;
+ struct cvmx_l2d_bst2_s cn31xx;
+ struct cvmx_l2d_bst2_s cn38xx;
+ struct cvmx_l2d_bst2_s cn38xxp2;
+ struct cvmx_l2d_bst2_s cn50xx;
+ struct cvmx_l2d_bst2_s cn52xx;
+ struct cvmx_l2d_bst2_s cn52xxp1;
+ struct cvmx_l2d_bst2_s cn56xx;
+ struct cvmx_l2d_bst2_s cn56xxp1;
+ struct cvmx_l2d_bst2_s cn58xx;
+ struct cvmx_l2d_bst2_s cn58xxp1;
+};
+
+union cvmx_l2d_bst3 {
+ uint64_t u64;
+ struct cvmx_l2d_bst3_s {
+ uint64_t reserved_34_63:30;
+ uint64_t q3stat:34;
+ } s;
+ struct cvmx_l2d_bst3_s cn30xx;
+ struct cvmx_l2d_bst3_s cn31xx;
+ struct cvmx_l2d_bst3_s cn38xx;
+ struct cvmx_l2d_bst3_s cn38xxp2;
+ struct cvmx_l2d_bst3_s cn50xx;
+ struct cvmx_l2d_bst3_s cn52xx;
+ struct cvmx_l2d_bst3_s cn52xxp1;
+ struct cvmx_l2d_bst3_s cn56xx;
+ struct cvmx_l2d_bst3_s cn56xxp1;
+ struct cvmx_l2d_bst3_s cn58xx;
+ struct cvmx_l2d_bst3_s cn58xxp1;
+};
+
+union cvmx_l2d_err {
+ uint64_t u64;
+ struct cvmx_l2d_err_s {
+ uint64_t reserved_6_63:58;
+ uint64_t bmhclsel:1;
+ uint64_t ded_err:1;
+ uint64_t sec_err:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_intena:1;
+ uint64_t ecc_ena:1;
+ } s;
+ struct cvmx_l2d_err_s cn30xx;
+ struct cvmx_l2d_err_s cn31xx;
+ struct cvmx_l2d_err_s cn38xx;
+ struct cvmx_l2d_err_s cn38xxp2;
+ struct cvmx_l2d_err_s cn50xx;
+ struct cvmx_l2d_err_s cn52xx;
+ struct cvmx_l2d_err_s cn52xxp1;
+ struct cvmx_l2d_err_s cn56xx;
+ struct cvmx_l2d_err_s cn56xxp1;
+ struct cvmx_l2d_err_s cn58xx;
+ struct cvmx_l2d_err_s cn58xxp1;
+};
+
+union cvmx_l2d_fadr {
+ uint64_t u64;
+ struct cvmx_l2d_fadr_s {
+ uint64_t reserved_19_63:45;
+ uint64_t fadru:1;
+ uint64_t fowmsk:4;
+ uint64_t fset:3;
+ uint64_t fadr:11;
+ } s;
+ struct cvmx_l2d_fadr_cn30xx {
+ uint64_t reserved_18_63:46;
+ uint64_t fowmsk:4;
+ uint64_t reserved_13_13:1;
+ uint64_t fset:2;
+ uint64_t reserved_9_10:2;
+ uint64_t fadr:9;
+ } cn30xx;
+ struct cvmx_l2d_fadr_cn31xx {
+ uint64_t reserved_18_63:46;
+ uint64_t fowmsk:4;
+ uint64_t reserved_13_13:1;
+ uint64_t fset:2;
+ uint64_t reserved_10_10:1;
+ uint64_t fadr:10;
+ } cn31xx;
+ struct cvmx_l2d_fadr_cn38xx {
+ uint64_t reserved_18_63:46;
+ uint64_t fowmsk:4;
+ uint64_t fset:3;
+ uint64_t fadr:11;
+ } cn38xx;
+ struct cvmx_l2d_fadr_cn38xx cn38xxp2;
+ struct cvmx_l2d_fadr_cn50xx {
+ uint64_t reserved_18_63:46;
+ uint64_t fowmsk:4;
+ uint64_t fset:3;
+ uint64_t reserved_8_10:3;
+ uint64_t fadr:8;
+ } cn50xx;
+ struct cvmx_l2d_fadr_cn52xx {
+ uint64_t reserved_18_63:46;
+ uint64_t fowmsk:4;
+ uint64_t fset:3;
+ uint64_t reserved_10_10:1;
+ uint64_t fadr:10;
+ } cn52xx;
+ struct cvmx_l2d_fadr_cn52xx cn52xxp1;
+ struct cvmx_l2d_fadr_s cn56xx;
+ struct cvmx_l2d_fadr_s cn56xxp1;
+ struct cvmx_l2d_fadr_s cn58xx;
+ struct cvmx_l2d_fadr_s cn58xxp1;
+};
+
+union cvmx_l2d_fsyn0 {
+ uint64_t u64;
+ struct cvmx_l2d_fsyn0_s {
+ uint64_t reserved_20_63:44;
+ uint64_t fsyn_ow1:10;
+ uint64_t fsyn_ow0:10;
+ } s;
+ struct cvmx_l2d_fsyn0_s cn30xx;
+ struct cvmx_l2d_fsyn0_s cn31xx;
+ struct cvmx_l2d_fsyn0_s cn38xx;
+ struct cvmx_l2d_fsyn0_s cn38xxp2;
+ struct cvmx_l2d_fsyn0_s cn50xx;
+ struct cvmx_l2d_fsyn0_s cn52xx;
+ struct cvmx_l2d_fsyn0_s cn52xxp1;
+ struct cvmx_l2d_fsyn0_s cn56xx;
+ struct cvmx_l2d_fsyn0_s cn56xxp1;
+ struct cvmx_l2d_fsyn0_s cn58xx;
+ struct cvmx_l2d_fsyn0_s cn58xxp1;
+};
+
+union cvmx_l2d_fsyn1 {
+ uint64_t u64;
+ struct cvmx_l2d_fsyn1_s {
+ uint64_t reserved_20_63:44;
+ uint64_t fsyn_ow3:10;
+ uint64_t fsyn_ow2:10;
+ } s;
+ struct cvmx_l2d_fsyn1_s cn30xx;
+ struct cvmx_l2d_fsyn1_s cn31xx;
+ struct cvmx_l2d_fsyn1_s cn38xx;
+ struct cvmx_l2d_fsyn1_s cn38xxp2;
+ struct cvmx_l2d_fsyn1_s cn50xx;
+ struct cvmx_l2d_fsyn1_s cn52xx;
+ struct cvmx_l2d_fsyn1_s cn52xxp1;
+ struct cvmx_l2d_fsyn1_s cn56xx;
+ struct cvmx_l2d_fsyn1_s cn56xxp1;
+ struct cvmx_l2d_fsyn1_s cn58xx;
+ struct cvmx_l2d_fsyn1_s cn58xxp1;
+};
+
+union cvmx_l2d_fus0 {
+ uint64_t u64;
+ struct cvmx_l2d_fus0_s {
+ uint64_t reserved_34_63:30;
+ uint64_t q0fus:34;
+ } s;
+ struct cvmx_l2d_fus0_s cn30xx;
+ struct cvmx_l2d_fus0_s cn31xx;
+ struct cvmx_l2d_fus0_s cn38xx;
+ struct cvmx_l2d_fus0_s cn38xxp2;
+ struct cvmx_l2d_fus0_s cn50xx;
+ struct cvmx_l2d_fus0_s cn52xx;
+ struct cvmx_l2d_fus0_s cn52xxp1;
+ struct cvmx_l2d_fus0_s cn56xx;
+ struct cvmx_l2d_fus0_s cn56xxp1;
+ struct cvmx_l2d_fus0_s cn58xx;
+ struct cvmx_l2d_fus0_s cn58xxp1;
+};
+
+union cvmx_l2d_fus1 {
+ uint64_t u64;
+ struct cvmx_l2d_fus1_s {
+ uint64_t reserved_34_63:30;
+ uint64_t q1fus:34;
+ } s;
+ struct cvmx_l2d_fus1_s cn30xx;
+ struct cvmx_l2d_fus1_s cn31xx;
+ struct cvmx_l2d_fus1_s cn38xx;
+ struct cvmx_l2d_fus1_s cn38xxp2;
+ struct cvmx_l2d_fus1_s cn50xx;
+ struct cvmx_l2d_fus1_s cn52xx;
+ struct cvmx_l2d_fus1_s cn52xxp1;
+ struct cvmx_l2d_fus1_s cn56xx;
+ struct cvmx_l2d_fus1_s cn56xxp1;
+ struct cvmx_l2d_fus1_s cn58xx;
+ struct cvmx_l2d_fus1_s cn58xxp1;
+};
+
+union cvmx_l2d_fus2 {
+ uint64_t u64;
+ struct cvmx_l2d_fus2_s {
+ uint64_t reserved_34_63:30;
+ uint64_t q2fus:34;
+ } s;
+ struct cvmx_l2d_fus2_s cn30xx;
+ struct cvmx_l2d_fus2_s cn31xx;
+ struct cvmx_l2d_fus2_s cn38xx;
+ struct cvmx_l2d_fus2_s cn38xxp2;
+ struct cvmx_l2d_fus2_s cn50xx;
+ struct cvmx_l2d_fus2_s cn52xx;
+ struct cvmx_l2d_fus2_s cn52xxp1;
+ struct cvmx_l2d_fus2_s cn56xx;
+ struct cvmx_l2d_fus2_s cn56xxp1;
+ struct cvmx_l2d_fus2_s cn58xx;
+ struct cvmx_l2d_fus2_s cn58xxp1;
+};
+
+union cvmx_l2d_fus3 {
+ uint64_t u64;
+ struct cvmx_l2d_fus3_s {
+ uint64_t reserved_40_63:24;
+ uint64_t ema_ctl:3;
+ uint64_t reserved_34_36:3;
+ uint64_t q3fus:34;
+ } s;
+ struct cvmx_l2d_fus3_cn30xx {
+ uint64_t reserved_35_63:29;
+ uint64_t crip_64k:1;
+ uint64_t q3fus:34;
+ } cn30xx;
+ struct cvmx_l2d_fus3_cn31xx {
+ uint64_t reserved_35_63:29;
+ uint64_t crip_128k:1;
+ uint64_t q3fus:34;
+ } cn31xx;
+ struct cvmx_l2d_fus3_cn38xx {
+ uint64_t reserved_36_63:28;
+ uint64_t crip_256k:1;
+ uint64_t crip_512k:1;
+ uint64_t q3fus:34;
+ } cn38xx;
+ struct cvmx_l2d_fus3_cn38xx cn38xxp2;
+ struct cvmx_l2d_fus3_cn50xx {
+ uint64_t reserved_40_63:24;
+ uint64_t ema_ctl:3;
+ uint64_t reserved_36_36:1;
+ uint64_t crip_32k:1;
+ uint64_t crip_64k:1;
+ uint64_t q3fus:34;
+ } cn50xx;
+ struct cvmx_l2d_fus3_cn52xx {
+ uint64_t reserved_40_63:24;
+ uint64_t ema_ctl:3;
+ uint64_t reserved_36_36:1;
+ uint64_t crip_128k:1;
+ uint64_t crip_256k:1;
+ uint64_t q3fus:34;
+ } cn52xx;
+ struct cvmx_l2d_fus3_cn52xx cn52xxp1;
+ struct cvmx_l2d_fus3_cn56xx {
+ uint64_t reserved_40_63:24;
+ uint64_t ema_ctl:3;
+ uint64_t reserved_36_36:1;
+ uint64_t crip_512k:1;
+ uint64_t crip_1024k:1;
+ uint64_t q3fus:34;
+ } cn56xx;
+ struct cvmx_l2d_fus3_cn56xx cn56xxp1;
+ struct cvmx_l2d_fus3_cn58xx {
+ uint64_t reserved_39_63:25;
+ uint64_t ema_ctl:2;
+ uint64_t reserved_36_36:1;
+ uint64_t crip_512k:1;
+ uint64_t crip_1024k:1;
+ uint64_t q3fus:34;
+ } cn58xx;
+ struct cvmx_l2d_fus3_cn58xx cn58xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-l2t-defs.h b/arch/mips/include/asm/octeon/cvmx-l2t-defs.h
new file mode 100644
index 0000000..2639a3f
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-l2t-defs.h
@@ -0,0 +1,141 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_L2T_DEFS_H__
+#define __CVMX_L2T_DEFS_H__
+
+#define CVMX_L2T_ERR \
+ CVMX_ADD_IO_SEG(0x0001180080000008ull)
+
+union cvmx_l2t_err {
+ uint64_t u64;
+ struct cvmx_l2t_err_s {
+ uint64_t reserved_29_63:35;
+ uint64_t fadru:1;
+ uint64_t lck_intena2:1;
+ uint64_t lckerr2:1;
+ uint64_t lck_intena:1;
+ uint64_t lckerr:1;
+ uint64_t fset:3;
+ uint64_t fadr:10;
+ uint64_t fsyn:6;
+ uint64_t ded_err:1;
+ uint64_t sec_err:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_intena:1;
+ uint64_t ecc_ena:1;
+ } s;
+ struct cvmx_l2t_err_cn30xx {
+ uint64_t reserved_28_63:36;
+ uint64_t lck_intena2:1;
+ uint64_t lckerr2:1;
+ uint64_t lck_intena:1;
+ uint64_t lckerr:1;
+ uint64_t reserved_23_23:1;
+ uint64_t fset:2;
+ uint64_t reserved_19_20:2;
+ uint64_t fadr:8;
+ uint64_t fsyn:6;
+ uint64_t ded_err:1;
+ uint64_t sec_err:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_intena:1;
+ uint64_t ecc_ena:1;
+ } cn30xx;
+ struct cvmx_l2t_err_cn31xx {
+ uint64_t reserved_28_63:36;
+ uint64_t lck_intena2:1;
+ uint64_t lckerr2:1;
+ uint64_t lck_intena:1;
+ uint64_t lckerr:1;
+ uint64_t reserved_23_23:1;
+ uint64_t fset:2;
+ uint64_t reserved_20_20:1;
+ uint64_t fadr:9;
+ uint64_t fsyn:6;
+ uint64_t ded_err:1;
+ uint64_t sec_err:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_intena:1;
+ uint64_t ecc_ena:1;
+ } cn31xx;
+ struct cvmx_l2t_err_cn38xx {
+ uint64_t reserved_28_63:36;
+ uint64_t lck_intena2:1;
+ uint64_t lckerr2:1;
+ uint64_t lck_intena:1;
+ uint64_t lckerr:1;
+ uint64_t fset:3;
+ uint64_t fadr:10;
+ uint64_t fsyn:6;
+ uint64_t ded_err:1;
+ uint64_t sec_err:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_intena:1;
+ uint64_t ecc_ena:1;
+ } cn38xx;
+ struct cvmx_l2t_err_cn38xx cn38xxp2;
+ struct cvmx_l2t_err_cn50xx {
+ uint64_t reserved_28_63:36;
+ uint64_t lck_intena2:1;
+ uint64_t lckerr2:1;
+ uint64_t lck_intena:1;
+ uint64_t lckerr:1;
+ uint64_t fset:3;
+ uint64_t reserved_18_20:3;
+ uint64_t fadr:7;
+ uint64_t fsyn:6;
+ uint64_t ded_err:1;
+ uint64_t sec_err:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_intena:1;
+ uint64_t ecc_ena:1;
+ } cn50xx;
+ struct cvmx_l2t_err_cn52xx {
+ uint64_t reserved_28_63:36;
+ uint64_t lck_intena2:1;
+ uint64_t lckerr2:1;
+ uint64_t lck_intena:1;
+ uint64_t lckerr:1;
+ uint64_t fset:3;
+ uint64_t reserved_20_20:1;
+ uint64_t fadr:9;
+ uint64_t fsyn:6;
+ uint64_t ded_err:1;
+ uint64_t sec_err:1;
+ uint64_t ded_intena:1;
+ uint64_t sec_intena:1;
+ uint64_t ecc_ena:1;
+ } cn52xx;
+ struct cvmx_l2t_err_cn52xx cn52xxp1;
+ struct cvmx_l2t_err_s cn56xx;
+ struct cvmx_l2t_err_s cn56xxp1;
+ struct cvmx_l2t_err_s cn58xx;
+ struct cvmx_l2t_err_s cn58xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-led-defs.h b/arch/mips/include/asm/octeon/cvmx-led-defs.h
new file mode 100644
index 0000000..16f174a
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-led-defs.h
@@ -0,0 +1,240 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_LED_DEFS_H__
+#define __CVMX_LED_DEFS_H__
+
+#define CVMX_LED_BLINK \
+ CVMX_ADD_IO_SEG(0x0001180000001A48ull)
+#define CVMX_LED_CLK_PHASE \
+ CVMX_ADD_IO_SEG(0x0001180000001A08ull)
+#define CVMX_LED_CYLON \
+ CVMX_ADD_IO_SEG(0x0001180000001AF8ull)
+#define CVMX_LED_DBG \
+ CVMX_ADD_IO_SEG(0x0001180000001A18ull)
+#define CVMX_LED_EN \
+ CVMX_ADD_IO_SEG(0x0001180000001A00ull)
+#define CVMX_LED_POLARITY \
+ CVMX_ADD_IO_SEG(0x0001180000001A50ull)
+#define CVMX_LED_PRT \
+ CVMX_ADD_IO_SEG(0x0001180000001A10ull)
+#define CVMX_LED_PRT_FMT \
+ CVMX_ADD_IO_SEG(0x0001180000001A30ull)
+#define CVMX_LED_PRT_STATUSX(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000001A80ull + (((offset) & 7) * 8))
+#define CVMX_LED_UDD_CNTX(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000001A20ull + (((offset) & 1) * 8))
+#define CVMX_LED_UDD_DATX(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000001A38ull + (((offset) & 1) * 8))
+#define CVMX_LED_UDD_DAT_CLRX(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000001AC8ull + (((offset) & 1) * 16))
+#define CVMX_LED_UDD_DAT_SETX(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000001AC0ull + (((offset) & 1) * 16))
+
+union cvmx_led_blink {
+ uint64_t u64;
+ struct cvmx_led_blink_s {
+ uint64_t reserved_8_63:56;
+ uint64_t rate:8;
+ } s;
+ struct cvmx_led_blink_s cn38xx;
+ struct cvmx_led_blink_s cn38xxp2;
+ struct cvmx_led_blink_s cn56xx;
+ struct cvmx_led_blink_s cn56xxp1;
+ struct cvmx_led_blink_s cn58xx;
+ struct cvmx_led_blink_s cn58xxp1;
+};
+
+union cvmx_led_clk_phase {
+ uint64_t u64;
+ struct cvmx_led_clk_phase_s {
+ uint64_t reserved_7_63:57;
+ uint64_t phase:7;
+ } s;
+ struct cvmx_led_clk_phase_s cn38xx;
+ struct cvmx_led_clk_phase_s cn38xxp2;
+ struct cvmx_led_clk_phase_s cn56xx;
+ struct cvmx_led_clk_phase_s cn56xxp1;
+ struct cvmx_led_clk_phase_s cn58xx;
+ struct cvmx_led_clk_phase_s cn58xxp1;
+};
+
+union cvmx_led_cylon {
+ uint64_t u64;
+ struct cvmx_led_cylon_s {
+ uint64_t reserved_16_63:48;
+ uint64_t rate:16;
+ } s;
+ struct cvmx_led_cylon_s cn38xx;
+ struct cvmx_led_cylon_s cn38xxp2;
+ struct cvmx_led_cylon_s cn56xx;
+ struct cvmx_led_cylon_s cn56xxp1;
+ struct cvmx_led_cylon_s cn58xx;
+ struct cvmx_led_cylon_s cn58xxp1;
+};
+
+union cvmx_led_dbg {
+ uint64_t u64;
+ struct cvmx_led_dbg_s {
+ uint64_t reserved_1_63:63;
+ uint64_t dbg_en:1;
+ } s;
+ struct cvmx_led_dbg_s cn38xx;
+ struct cvmx_led_dbg_s cn38xxp2;
+ struct cvmx_led_dbg_s cn56xx;
+ struct cvmx_led_dbg_s cn56xxp1;
+ struct cvmx_led_dbg_s cn58xx;
+ struct cvmx_led_dbg_s cn58xxp1;
+};
+
+union cvmx_led_en {
+ uint64_t u64;
+ struct cvmx_led_en_s {
+ uint64_t reserved_1_63:63;
+ uint64_t en:1;
+ } s;
+ struct cvmx_led_en_s cn38xx;
+ struct cvmx_led_en_s cn38xxp2;
+ struct cvmx_led_en_s cn56xx;
+ struct cvmx_led_en_s cn56xxp1;
+ struct cvmx_led_en_s cn58xx;
+ struct cvmx_led_en_s cn58xxp1;
+};
+
+union cvmx_led_polarity {
+ uint64_t u64;
+ struct cvmx_led_polarity_s {
+ uint64_t reserved_1_63:63;
+ uint64_t polarity:1;
+ } s;
+ struct cvmx_led_polarity_s cn38xx;
+ struct cvmx_led_polarity_s cn38xxp2;
+ struct cvmx_led_polarity_s cn56xx;
+ struct cvmx_led_polarity_s cn56xxp1;
+ struct cvmx_led_polarity_s cn58xx;
+ struct cvmx_led_polarity_s cn58xxp1;
+};
+
+union cvmx_led_prt {
+ uint64_t u64;
+ struct cvmx_led_prt_s {
+ uint64_t reserved_8_63:56;
+ uint64_t prt_en:8;
+ } s;
+ struct cvmx_led_prt_s cn38xx;
+ struct cvmx_led_prt_s cn38xxp2;
+ struct cvmx_led_prt_s cn56xx;
+ struct cvmx_led_prt_s cn56xxp1;
+ struct cvmx_led_prt_s cn58xx;
+ struct cvmx_led_prt_s cn58xxp1;
+};
+
+union cvmx_led_prt_fmt {
+ uint64_t u64;
+ struct cvmx_led_prt_fmt_s {
+ uint64_t reserved_4_63:60;
+ uint64_t format:4;
+ } s;
+ struct cvmx_led_prt_fmt_s cn38xx;
+ struct cvmx_led_prt_fmt_s cn38xxp2;
+ struct cvmx_led_prt_fmt_s cn56xx;
+ struct cvmx_led_prt_fmt_s cn56xxp1;
+ struct cvmx_led_prt_fmt_s cn58xx;
+ struct cvmx_led_prt_fmt_s cn58xxp1;
+};
+
+union cvmx_led_prt_statusx {
+ uint64_t u64;
+ struct cvmx_led_prt_statusx_s {
+ uint64_t reserved_6_63:58;
+ uint64_t status:6;
+ } s;
+ struct cvmx_led_prt_statusx_s cn38xx;
+ struct cvmx_led_prt_statusx_s cn38xxp2;
+ struct cvmx_led_prt_statusx_s cn56xx;
+ struct cvmx_led_prt_statusx_s cn56xxp1;
+ struct cvmx_led_prt_statusx_s cn58xx;
+ struct cvmx_led_prt_statusx_s cn58xxp1;
+};
+
+union cvmx_led_udd_cntx {
+ uint64_t u64;
+ struct cvmx_led_udd_cntx_s {
+ uint64_t reserved_6_63:58;
+ uint64_t cnt:6;
+ } s;
+ struct cvmx_led_udd_cntx_s cn38xx;
+ struct cvmx_led_udd_cntx_s cn38xxp2;
+ struct cvmx_led_udd_cntx_s cn56xx;
+ struct cvmx_led_udd_cntx_s cn56xxp1;
+ struct cvmx_led_udd_cntx_s cn58xx;
+ struct cvmx_led_udd_cntx_s cn58xxp1;
+};
+
+union cvmx_led_udd_datx {
+ uint64_t u64;
+ struct cvmx_led_udd_datx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t dat:32;
+ } s;
+ struct cvmx_led_udd_datx_s cn38xx;
+ struct cvmx_led_udd_datx_s cn38xxp2;
+ struct cvmx_led_udd_datx_s cn56xx;
+ struct cvmx_led_udd_datx_s cn56xxp1;
+ struct cvmx_led_udd_datx_s cn58xx;
+ struct cvmx_led_udd_datx_s cn58xxp1;
+};
+
+union cvmx_led_udd_dat_clrx {
+ uint64_t u64;
+ struct cvmx_led_udd_dat_clrx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t clr:32;
+ } s;
+ struct cvmx_led_udd_dat_clrx_s cn38xx;
+ struct cvmx_led_udd_dat_clrx_s cn38xxp2;
+ struct cvmx_led_udd_dat_clrx_s cn56xx;
+ struct cvmx_led_udd_dat_clrx_s cn56xxp1;
+ struct cvmx_led_udd_dat_clrx_s cn58xx;
+ struct cvmx_led_udd_dat_clrx_s cn58xxp1;
+};
+
+union cvmx_led_udd_dat_setx {
+ uint64_t u64;
+ struct cvmx_led_udd_dat_setx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t set:32;
+ } s;
+ struct cvmx_led_udd_dat_setx_s cn38xx;
+ struct cvmx_led_udd_dat_setx_s cn38xxp2;
+ struct cvmx_led_udd_dat_setx_s cn56xx;
+ struct cvmx_led_udd_dat_setx_s cn56xxp1;
+ struct cvmx_led_udd_dat_setx_s cn58xx;
+ struct cvmx_led_udd_dat_setx_s cn58xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-mio-defs.h b/arch/mips/include/asm/octeon/cvmx-mio-defs.h
new file mode 100644
index 0000000..6555f05
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-mio-defs.h
@@ -0,0 +1,2004 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_MIO_DEFS_H__
+#define __CVMX_MIO_DEFS_H__
+
+#define CVMX_MIO_BOOT_BIST_STAT \
+ CVMX_ADD_IO_SEG(0x00011800000000F8ull)
+#define CVMX_MIO_BOOT_COMP \
+ CVMX_ADD_IO_SEG(0x00011800000000B8ull)
+#define CVMX_MIO_BOOT_DMA_CFGX(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000100ull + (((offset) & 3) * 8))
+#define CVMX_MIO_BOOT_DMA_INTX(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000138ull + (((offset) & 3) * 8))
+#define CVMX_MIO_BOOT_DMA_INT_ENX(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000150ull + (((offset) & 3) * 8))
+#define CVMX_MIO_BOOT_DMA_TIMX(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000120ull + (((offset) & 3) * 8))
+#define CVMX_MIO_BOOT_ERR \
+ CVMX_ADD_IO_SEG(0x00011800000000A0ull)
+#define CVMX_MIO_BOOT_INT \
+ CVMX_ADD_IO_SEG(0x00011800000000A8ull)
+#define CVMX_MIO_BOOT_LOC_ADR \
+ CVMX_ADD_IO_SEG(0x0001180000000090ull)
+#define CVMX_MIO_BOOT_LOC_CFGX(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000080ull + (((offset) & 1) * 8))
+#define CVMX_MIO_BOOT_LOC_DAT \
+ CVMX_ADD_IO_SEG(0x0001180000000098ull)
+#define CVMX_MIO_BOOT_PIN_DEFS \
+ CVMX_ADD_IO_SEG(0x00011800000000C0ull)
+#define CVMX_MIO_BOOT_REG_CFGX(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000000ull + (((offset) & 7) * 8))
+#define CVMX_MIO_BOOT_REG_TIMX(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000040ull + (((offset) & 7) * 8))
+#define CVMX_MIO_BOOT_THR \
+ CVMX_ADD_IO_SEG(0x00011800000000B0ull)
+#define CVMX_MIO_FUS_BNK_DATX(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000001520ull + (((offset) & 3) * 8))
+#define CVMX_MIO_FUS_DAT0 \
+ CVMX_ADD_IO_SEG(0x0001180000001400ull)
+#define CVMX_MIO_FUS_DAT1 \
+ CVMX_ADD_IO_SEG(0x0001180000001408ull)
+#define CVMX_MIO_FUS_DAT2 \
+ CVMX_ADD_IO_SEG(0x0001180000001410ull)
+#define CVMX_MIO_FUS_DAT3 \
+ CVMX_ADD_IO_SEG(0x0001180000001418ull)
+#define CVMX_MIO_FUS_EMA \
+ CVMX_ADD_IO_SEG(0x0001180000001550ull)
+#define CVMX_MIO_FUS_PDF \
+ CVMX_ADD_IO_SEG(0x0001180000001420ull)
+#define CVMX_MIO_FUS_PLL \
+ CVMX_ADD_IO_SEG(0x0001180000001580ull)
+#define CVMX_MIO_FUS_PROG \
+ CVMX_ADD_IO_SEG(0x0001180000001510ull)
+#define CVMX_MIO_FUS_PROG_TIMES \
+ CVMX_ADD_IO_SEG(0x0001180000001518ull)
+#define CVMX_MIO_FUS_RCMD \
+ CVMX_ADD_IO_SEG(0x0001180000001500ull)
+#define CVMX_MIO_FUS_SPR_REPAIR_RES \
+ CVMX_ADD_IO_SEG(0x0001180000001548ull)
+#define CVMX_MIO_FUS_SPR_REPAIR_SUM \
+ CVMX_ADD_IO_SEG(0x0001180000001540ull)
+#define CVMX_MIO_FUS_UNLOCK \
+ CVMX_ADD_IO_SEG(0x0001180000001578ull)
+#define CVMX_MIO_FUS_WADR \
+ CVMX_ADD_IO_SEG(0x0001180000001508ull)
+#define CVMX_MIO_NDF_DMA_CFG \
+ CVMX_ADD_IO_SEG(0x0001180000000168ull)
+#define CVMX_MIO_NDF_DMA_INT \
+ CVMX_ADD_IO_SEG(0x0001180000000170ull)
+#define CVMX_MIO_NDF_DMA_INT_EN \
+ CVMX_ADD_IO_SEG(0x0001180000000178ull)
+#define CVMX_MIO_PLL_CTL \
+ CVMX_ADD_IO_SEG(0x0001180000001448ull)
+#define CVMX_MIO_PLL_SETTING \
+ CVMX_ADD_IO_SEG(0x0001180000001440ull)
+#define CVMX_MIO_TWSX_INT(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000001010ull + (((offset) & 1) * 512))
+#define CVMX_MIO_TWSX_SW_TWSI(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000001000ull + (((offset) & 1) * 512))
+#define CVMX_MIO_TWSX_SW_TWSI_EXT(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000001018ull + (((offset) & 1) * 512))
+#define CVMX_MIO_TWSX_TWSI_SW(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000001008ull + (((offset) & 1) * 512))
+#define CVMX_MIO_UART2_DLH \
+ CVMX_ADD_IO_SEG(0x0001180000000488ull)
+#define CVMX_MIO_UART2_DLL \
+ CVMX_ADD_IO_SEG(0x0001180000000480ull)
+#define CVMX_MIO_UART2_FAR \
+ CVMX_ADD_IO_SEG(0x0001180000000520ull)
+#define CVMX_MIO_UART2_FCR \
+ CVMX_ADD_IO_SEG(0x0001180000000450ull)
+#define CVMX_MIO_UART2_HTX \
+ CVMX_ADD_IO_SEG(0x0001180000000708ull)
+#define CVMX_MIO_UART2_IER \
+ CVMX_ADD_IO_SEG(0x0001180000000408ull)
+#define CVMX_MIO_UART2_IIR \
+ CVMX_ADD_IO_SEG(0x0001180000000410ull)
+#define CVMX_MIO_UART2_LCR \
+ CVMX_ADD_IO_SEG(0x0001180000000418ull)
+#define CVMX_MIO_UART2_LSR \
+ CVMX_ADD_IO_SEG(0x0001180000000428ull)
+#define CVMX_MIO_UART2_MCR \
+ CVMX_ADD_IO_SEG(0x0001180000000420ull)
+#define CVMX_MIO_UART2_MSR \
+ CVMX_ADD_IO_SEG(0x0001180000000430ull)
+#define CVMX_MIO_UART2_RBR \
+ CVMX_ADD_IO_SEG(0x0001180000000400ull)
+#define CVMX_MIO_UART2_RFL \
+ CVMX_ADD_IO_SEG(0x0001180000000608ull)
+#define CVMX_MIO_UART2_RFW \
+ CVMX_ADD_IO_SEG(0x0001180000000530ull)
+#define CVMX_MIO_UART2_SBCR \
+ CVMX_ADD_IO_SEG(0x0001180000000620ull)
+#define CVMX_MIO_UART2_SCR \
+ CVMX_ADD_IO_SEG(0x0001180000000438ull)
+#define CVMX_MIO_UART2_SFE \
+ CVMX_ADD_IO_SEG(0x0001180000000630ull)
+#define CVMX_MIO_UART2_SRR \
+ CVMX_ADD_IO_SEG(0x0001180000000610ull)
+#define CVMX_MIO_UART2_SRT \
+ CVMX_ADD_IO_SEG(0x0001180000000638ull)
+#define CVMX_MIO_UART2_SRTS \
+ CVMX_ADD_IO_SEG(0x0001180000000618ull)
+#define CVMX_MIO_UART2_STT \
+ CVMX_ADD_IO_SEG(0x0001180000000700ull)
+#define CVMX_MIO_UART2_TFL \
+ CVMX_ADD_IO_SEG(0x0001180000000600ull)
+#define CVMX_MIO_UART2_TFR \
+ CVMX_ADD_IO_SEG(0x0001180000000528ull)
+#define CVMX_MIO_UART2_THR \
+ CVMX_ADD_IO_SEG(0x0001180000000440ull)
+#define CVMX_MIO_UART2_USR \
+ CVMX_ADD_IO_SEG(0x0001180000000538ull)
+#define CVMX_MIO_UARTX_DLH(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000888ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_DLL(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000880ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_FAR(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000920ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_FCR(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000850ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_HTX(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000B08ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_IER(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000808ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_IIR(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000810ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_LCR(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000818ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_LSR(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000828ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_MCR(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000820ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_MSR(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000830ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_RBR(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000800ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_RFL(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000A08ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_RFW(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000930ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_SBCR(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000A20ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_SCR(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000838ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_SFE(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000A30ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_SRR(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000A10ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_SRT(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000A38ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_SRTS(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000A18ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_STT(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000B00ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_TFL(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000A00ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_TFR(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000928ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_THR(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000840ull + (((offset) & 1) * 1024))
+#define CVMX_MIO_UARTX_USR(offset) \
+ CVMX_ADD_IO_SEG(0x0001180000000938ull + (((offset) & 1) * 1024))
+
+union cvmx_mio_boot_bist_stat {
+ uint64_t u64;
+ struct cvmx_mio_boot_bist_stat_s {
+ uint64_t reserved_2_63:62;
+ uint64_t loc:1;
+ uint64_t ncbi:1;
+ } s;
+ struct cvmx_mio_boot_bist_stat_cn30xx {
+ uint64_t reserved_4_63:60;
+ uint64_t ncbo_1:1;
+ uint64_t ncbo_0:1;
+ uint64_t loc:1;
+ uint64_t ncbi:1;
+ } cn30xx;
+ struct cvmx_mio_boot_bist_stat_cn30xx cn31xx;
+ struct cvmx_mio_boot_bist_stat_cn38xx {
+ uint64_t reserved_3_63:61;
+ uint64_t ncbo_0:1;
+ uint64_t loc:1;
+ uint64_t ncbi:1;
+ } cn38xx;
+ struct cvmx_mio_boot_bist_stat_cn38xx cn38xxp2;
+ struct cvmx_mio_boot_bist_stat_cn50xx {
+ uint64_t reserved_6_63:58;
+ uint64_t pcm_1:1;
+ uint64_t pcm_0:1;
+ uint64_t ncbo_1:1;
+ uint64_t ncbo_0:1;
+ uint64_t loc:1;
+ uint64_t ncbi:1;
+ } cn50xx;
+ struct cvmx_mio_boot_bist_stat_cn52xx {
+ uint64_t reserved_6_63:58;
+ uint64_t ndf:2;
+ uint64_t ncbo_0:1;
+ uint64_t dma:1;
+ uint64_t loc:1;
+ uint64_t ncbi:1;
+ } cn52xx;
+ struct cvmx_mio_boot_bist_stat_cn52xxp1 {
+ uint64_t reserved_4_63:60;
+ uint64_t ncbo_0:1;
+ uint64_t dma:1;
+ uint64_t loc:1;
+ uint64_t ncbi:1;
+ } cn52xxp1;
+ struct cvmx_mio_boot_bist_stat_cn52xxp1 cn56xx;
+ struct cvmx_mio_boot_bist_stat_cn52xxp1 cn56xxp1;
+ struct cvmx_mio_boot_bist_stat_cn38xx cn58xx;
+ struct cvmx_mio_boot_bist_stat_cn38xx cn58xxp1;
+};
+
+union cvmx_mio_boot_comp {
+ uint64_t u64;
+ struct cvmx_mio_boot_comp_s {
+ uint64_t reserved_10_63:54;
+ uint64_t pctl:5;
+ uint64_t nctl:5;
+ } s;
+ struct cvmx_mio_boot_comp_s cn50xx;
+ struct cvmx_mio_boot_comp_s cn52xx;
+ struct cvmx_mio_boot_comp_s cn52xxp1;
+ struct cvmx_mio_boot_comp_s cn56xx;
+ struct cvmx_mio_boot_comp_s cn56xxp1;
+};
+
+union cvmx_mio_boot_dma_cfgx {
+ uint64_t u64;
+ struct cvmx_mio_boot_dma_cfgx_s {
+ uint64_t en:1;
+ uint64_t rw:1;
+ uint64_t clr:1;
+ uint64_t reserved_60_60:1;
+ uint64_t swap32:1;
+ uint64_t swap16:1;
+ uint64_t swap8:1;
+ uint64_t endian:1;
+ uint64_t size:20;
+ uint64_t adr:36;
+ } s;
+ struct cvmx_mio_boot_dma_cfgx_s cn52xx;
+ struct cvmx_mio_boot_dma_cfgx_s cn52xxp1;
+ struct cvmx_mio_boot_dma_cfgx_s cn56xx;
+ struct cvmx_mio_boot_dma_cfgx_s cn56xxp1;
+};
+
+union cvmx_mio_boot_dma_intx {
+ uint64_t u64;
+ struct cvmx_mio_boot_dma_intx_s {
+ uint64_t reserved_2_63:62;
+ uint64_t dmarq:1;
+ uint64_t done:1;
+ } s;
+ struct cvmx_mio_boot_dma_intx_s cn52xx;
+ struct cvmx_mio_boot_dma_intx_s cn52xxp1;
+ struct cvmx_mio_boot_dma_intx_s cn56xx;
+ struct cvmx_mio_boot_dma_intx_s cn56xxp1;
+};
+
+union cvmx_mio_boot_dma_int_enx {
+ uint64_t u64;
+ struct cvmx_mio_boot_dma_int_enx_s {
+ uint64_t reserved_2_63:62;
+ uint64_t dmarq:1;
+ uint64_t done:1;
+ } s;
+ struct cvmx_mio_boot_dma_int_enx_s cn52xx;
+ struct cvmx_mio_boot_dma_int_enx_s cn52xxp1;
+ struct cvmx_mio_boot_dma_int_enx_s cn56xx;
+ struct cvmx_mio_boot_dma_int_enx_s cn56xxp1;
+};
+
+union cvmx_mio_boot_dma_timx {
+ uint64_t u64;
+ struct cvmx_mio_boot_dma_timx_s {
+ uint64_t dmack_pi:1;
+ uint64_t dmarq_pi:1;
+ uint64_t tim_mult:2;
+ uint64_t rd_dly:3;
+ uint64_t ddr:1;
+ uint64_t width:1;
+ uint64_t reserved_48_54:7;
+ uint64_t pause:6;
+ uint64_t dmack_h:6;
+ uint64_t we_n:6;
+ uint64_t we_a:6;
+ uint64_t oe_n:6;
+ uint64_t oe_a:6;
+ uint64_t dmack_s:6;
+ uint64_t dmarq:6;
+ } s;
+ struct cvmx_mio_boot_dma_timx_s cn52xx;
+ struct cvmx_mio_boot_dma_timx_s cn52xxp1;
+ struct cvmx_mio_boot_dma_timx_s cn56xx;
+ struct cvmx_mio_boot_dma_timx_s cn56xxp1;
+};
+
+union cvmx_mio_boot_err {
+ uint64_t u64;
+ struct cvmx_mio_boot_err_s {
+ uint64_t reserved_2_63:62;
+ uint64_t wait_err:1;
+ uint64_t adr_err:1;
+ } s;
+ struct cvmx_mio_boot_err_s cn30xx;
+ struct cvmx_mio_boot_err_s cn31xx;
+ struct cvmx_mio_boot_err_s cn38xx;
+ struct cvmx_mio_boot_err_s cn38xxp2;
+ struct cvmx_mio_boot_err_s cn50xx;
+ struct cvmx_mio_boot_err_s cn52xx;
+ struct cvmx_mio_boot_err_s cn52xxp1;
+ struct cvmx_mio_boot_err_s cn56xx;
+ struct cvmx_mio_boot_err_s cn56xxp1;
+ struct cvmx_mio_boot_err_s cn58xx;
+ struct cvmx_mio_boot_err_s cn58xxp1;
+};
+
+union cvmx_mio_boot_int {
+ uint64_t u64;
+ struct cvmx_mio_boot_int_s {
+ uint64_t reserved_2_63:62;
+ uint64_t wait_int:1;
+ uint64_t adr_int:1;
+ } s;
+ struct cvmx_mio_boot_int_s cn30xx;
+ struct cvmx_mio_boot_int_s cn31xx;
+ struct cvmx_mio_boot_int_s cn38xx;
+ struct cvmx_mio_boot_int_s cn38xxp2;
+ struct cvmx_mio_boot_int_s cn50xx;
+ struct cvmx_mio_boot_int_s cn52xx;
+ struct cvmx_mio_boot_int_s cn52xxp1;
+ struct cvmx_mio_boot_int_s cn56xx;
+ struct cvmx_mio_boot_int_s cn56xxp1;
+ struct cvmx_mio_boot_int_s cn58xx;
+ struct cvmx_mio_boot_int_s cn58xxp1;
+};
+
+union cvmx_mio_boot_loc_adr {
+ uint64_t u64;
+ struct cvmx_mio_boot_loc_adr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t adr:5;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_mio_boot_loc_adr_s cn30xx;
+ struct cvmx_mio_boot_loc_adr_s cn31xx;
+ struct cvmx_mio_boot_loc_adr_s cn38xx;
+ struct cvmx_mio_boot_loc_adr_s cn38xxp2;
+ struct cvmx_mio_boot_loc_adr_s cn50xx;
+ struct cvmx_mio_boot_loc_adr_s cn52xx;
+ struct cvmx_mio_boot_loc_adr_s cn52xxp1;
+ struct cvmx_mio_boot_loc_adr_s cn56xx;
+ struct cvmx_mio_boot_loc_adr_s cn56xxp1;
+ struct cvmx_mio_boot_loc_adr_s cn58xx;
+ struct cvmx_mio_boot_loc_adr_s cn58xxp1;
+};
+
+union cvmx_mio_boot_loc_cfgx {
+ uint64_t u64;
+ struct cvmx_mio_boot_loc_cfgx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t en:1;
+ uint64_t reserved_28_30:3;
+ uint64_t base:25;
+ uint64_t reserved_0_2:3;
+ } s;
+ struct cvmx_mio_boot_loc_cfgx_s cn30xx;
+ struct cvmx_mio_boot_loc_cfgx_s cn31xx;
+ struct cvmx_mio_boot_loc_cfgx_s cn38xx;
+ struct cvmx_mio_boot_loc_cfgx_s cn38xxp2;
+ struct cvmx_mio_boot_loc_cfgx_s cn50xx;
+ struct cvmx_mio_boot_loc_cfgx_s cn52xx;
+ struct cvmx_mio_boot_loc_cfgx_s cn52xxp1;
+ struct cvmx_mio_boot_loc_cfgx_s cn56xx;
+ struct cvmx_mio_boot_loc_cfgx_s cn56xxp1;
+ struct cvmx_mio_boot_loc_cfgx_s cn58xx;
+ struct cvmx_mio_boot_loc_cfgx_s cn58xxp1;
+};
+
+union cvmx_mio_boot_loc_dat {
+ uint64_t u64;
+ struct cvmx_mio_boot_loc_dat_s {
+ uint64_t data:64;
+ } s;
+ struct cvmx_mio_boot_loc_dat_s cn30xx;
+ struct cvmx_mio_boot_loc_dat_s cn31xx;
+ struct cvmx_mio_boot_loc_dat_s cn38xx;
+ struct cvmx_mio_boot_loc_dat_s cn38xxp2;
+ struct cvmx_mio_boot_loc_dat_s cn50xx;
+ struct cvmx_mio_boot_loc_dat_s cn52xx;
+ struct cvmx_mio_boot_loc_dat_s cn52xxp1;
+ struct cvmx_mio_boot_loc_dat_s cn56xx;
+ struct cvmx_mio_boot_loc_dat_s cn56xxp1;
+ struct cvmx_mio_boot_loc_dat_s cn58xx;
+ struct cvmx_mio_boot_loc_dat_s cn58xxp1;
+};
+
+union cvmx_mio_boot_pin_defs {
+ uint64_t u64;
+ struct cvmx_mio_boot_pin_defs_s {
+ uint64_t reserved_16_63:48;
+ uint64_t ale:1;
+ uint64_t width:1;
+ uint64_t dmack_p2:1;
+ uint64_t dmack_p1:1;
+ uint64_t dmack_p0:1;
+ uint64_t term:2;
+ uint64_t nand:1;
+ uint64_t reserved_0_7:8;
+ } s;
+ struct cvmx_mio_boot_pin_defs_cn52xx {
+ uint64_t reserved_16_63:48;
+ uint64_t ale:1;
+ uint64_t width:1;
+ uint64_t reserved_13_13:1;
+ uint64_t dmack_p1:1;
+ uint64_t dmack_p0:1;
+ uint64_t term:2;
+ uint64_t nand:1;
+ uint64_t reserved_0_7:8;
+ } cn52xx;
+ struct cvmx_mio_boot_pin_defs_cn56xx {
+ uint64_t reserved_16_63:48;
+ uint64_t ale:1;
+ uint64_t width:1;
+ uint64_t dmack_p2:1;
+ uint64_t dmack_p1:1;
+ uint64_t dmack_p0:1;
+ uint64_t term:2;
+ uint64_t reserved_0_8:9;
+ } cn56xx;
+};
+
+union cvmx_mio_boot_reg_cfgx {
+ uint64_t u64;
+ struct cvmx_mio_boot_reg_cfgx_s {
+ uint64_t reserved_44_63:20;
+ uint64_t dmack:2;
+ uint64_t tim_mult:2;
+ uint64_t rd_dly:3;
+ uint64_t sam:1;
+ uint64_t we_ext:2;
+ uint64_t oe_ext:2;
+ uint64_t en:1;
+ uint64_t orbit:1;
+ uint64_t ale:1;
+ uint64_t width:1;
+ uint64_t size:12;
+ uint64_t base:16;
+ } s;
+ struct cvmx_mio_boot_reg_cfgx_cn30xx {
+ uint64_t reserved_37_63:27;
+ uint64_t sam:1;
+ uint64_t we_ext:2;
+ uint64_t oe_ext:2;
+ uint64_t en:1;
+ uint64_t orbit:1;
+ uint64_t ale:1;
+ uint64_t width:1;
+ uint64_t size:12;
+ uint64_t base:16;
+ } cn30xx;
+ struct cvmx_mio_boot_reg_cfgx_cn30xx cn31xx;
+ struct cvmx_mio_boot_reg_cfgx_cn38xx {
+ uint64_t reserved_32_63:32;
+ uint64_t en:1;
+ uint64_t orbit:1;
+ uint64_t reserved_28_29:2;
+ uint64_t size:12;
+ uint64_t base:16;
+ } cn38xx;
+ struct cvmx_mio_boot_reg_cfgx_cn38xx cn38xxp2;
+ struct cvmx_mio_boot_reg_cfgx_cn50xx {
+ uint64_t reserved_42_63:22;
+ uint64_t tim_mult:2;
+ uint64_t rd_dly:3;
+ uint64_t sam:1;
+ uint64_t we_ext:2;
+ uint64_t oe_ext:2;
+ uint64_t en:1;
+ uint64_t orbit:1;
+ uint64_t ale:1;
+ uint64_t width:1;
+ uint64_t size:12;
+ uint64_t base:16;
+ } cn50xx;
+ struct cvmx_mio_boot_reg_cfgx_s cn52xx;
+ struct cvmx_mio_boot_reg_cfgx_s cn52xxp1;
+ struct cvmx_mio_boot_reg_cfgx_s cn56xx;
+ struct cvmx_mio_boot_reg_cfgx_s cn56xxp1;
+ struct cvmx_mio_boot_reg_cfgx_cn30xx cn58xx;
+ struct cvmx_mio_boot_reg_cfgx_cn30xx cn58xxp1;
+};
+
+union cvmx_mio_boot_reg_timx {
+ uint64_t u64;
+ struct cvmx_mio_boot_reg_timx_s {
+ uint64_t pagem:1;
+ uint64_t waitm:1;
+ uint64_t pages:2;
+ uint64_t ale:6;
+ uint64_t page:6;
+ uint64_t wait:6;
+ uint64_t pause:6;
+ uint64_t wr_hld:6;
+ uint64_t rd_hld:6;
+ uint64_t we:6;
+ uint64_t oe:6;
+ uint64_t ce:6;
+ uint64_t adr:6;
+ } s;
+ struct cvmx_mio_boot_reg_timx_s cn30xx;
+ struct cvmx_mio_boot_reg_timx_s cn31xx;
+ struct cvmx_mio_boot_reg_timx_cn38xx {
+ uint64_t pagem:1;
+ uint64_t waitm:1;
+ uint64_t pages:2;
+ uint64_t reserved_54_59:6;
+ uint64_t page:6;
+ uint64_t wait:6;
+ uint64_t pause:6;
+ uint64_t wr_hld:6;
+ uint64_t rd_hld:6;
+ uint64_t we:6;
+ uint64_t oe:6;
+ uint64_t ce:6;
+ uint64_t adr:6;
+ } cn38xx;
+ struct cvmx_mio_boot_reg_timx_cn38xx cn38xxp2;
+ struct cvmx_mio_boot_reg_timx_s cn50xx;
+ struct cvmx_mio_boot_reg_timx_s cn52xx;
+ struct cvmx_mio_boot_reg_timx_s cn52xxp1;
+ struct cvmx_mio_boot_reg_timx_s cn56xx;
+ struct cvmx_mio_boot_reg_timx_s cn56xxp1;
+ struct cvmx_mio_boot_reg_timx_s cn58xx;
+ struct cvmx_mio_boot_reg_timx_s cn58xxp1;
+};
+
+union cvmx_mio_boot_thr {
+ uint64_t u64;
+ struct cvmx_mio_boot_thr_s {
+ uint64_t reserved_22_63:42;
+ uint64_t dma_thr:6;
+ uint64_t reserved_14_15:2;
+ uint64_t fif_cnt:6;
+ uint64_t reserved_6_7:2;
+ uint64_t fif_thr:6;
+ } s;
+ struct cvmx_mio_boot_thr_cn30xx {
+ uint64_t reserved_14_63:50;
+ uint64_t fif_cnt:6;
+ uint64_t reserved_6_7:2;
+ uint64_t fif_thr:6;
+ } cn30xx;
+ struct cvmx_mio_boot_thr_cn30xx cn31xx;
+ struct cvmx_mio_boot_thr_cn30xx cn38xx;
+ struct cvmx_mio_boot_thr_cn30xx cn38xxp2;
+ struct cvmx_mio_boot_thr_cn30xx cn50xx;
+ struct cvmx_mio_boot_thr_s cn52xx;
+ struct cvmx_mio_boot_thr_s cn52xxp1;
+ struct cvmx_mio_boot_thr_s cn56xx;
+ struct cvmx_mio_boot_thr_s cn56xxp1;
+ struct cvmx_mio_boot_thr_cn30xx cn58xx;
+ struct cvmx_mio_boot_thr_cn30xx cn58xxp1;
+};
+
+union cvmx_mio_fus_bnk_datx {
+ uint64_t u64;
+ struct cvmx_mio_fus_bnk_datx_s {
+ uint64_t dat:64;
+ } s;
+ struct cvmx_mio_fus_bnk_datx_s cn50xx;
+ struct cvmx_mio_fus_bnk_datx_s cn52xx;
+ struct cvmx_mio_fus_bnk_datx_s cn52xxp1;
+ struct cvmx_mio_fus_bnk_datx_s cn56xx;
+ struct cvmx_mio_fus_bnk_datx_s cn56xxp1;
+ struct cvmx_mio_fus_bnk_datx_s cn58xx;
+ struct cvmx_mio_fus_bnk_datx_s cn58xxp1;
+};
+
+union cvmx_mio_fus_dat0 {
+ uint64_t u64;
+ struct cvmx_mio_fus_dat0_s {
+ uint64_t reserved_32_63:32;
+ uint64_t man_info:32;
+ } s;
+ struct cvmx_mio_fus_dat0_s cn30xx;
+ struct cvmx_mio_fus_dat0_s cn31xx;
+ struct cvmx_mio_fus_dat0_s cn38xx;
+ struct cvmx_mio_fus_dat0_s cn38xxp2;
+ struct cvmx_mio_fus_dat0_s cn50xx;
+ struct cvmx_mio_fus_dat0_s cn52xx;
+ struct cvmx_mio_fus_dat0_s cn52xxp1;
+ struct cvmx_mio_fus_dat0_s cn56xx;
+ struct cvmx_mio_fus_dat0_s cn56xxp1;
+ struct cvmx_mio_fus_dat0_s cn58xx;
+ struct cvmx_mio_fus_dat0_s cn58xxp1;
+};
+
+union cvmx_mio_fus_dat1 {
+ uint64_t u64;
+ struct cvmx_mio_fus_dat1_s {
+ uint64_t reserved_32_63:32;
+ uint64_t man_info:32;
+ } s;
+ struct cvmx_mio_fus_dat1_s cn30xx;
+ struct cvmx_mio_fus_dat1_s cn31xx;
+ struct cvmx_mio_fus_dat1_s cn38xx;
+ struct cvmx_mio_fus_dat1_s cn38xxp2;
+ struct cvmx_mio_fus_dat1_s cn50xx;
+ struct cvmx_mio_fus_dat1_s cn52xx;
+ struct cvmx_mio_fus_dat1_s cn52xxp1;
+ struct cvmx_mio_fus_dat1_s cn56xx;
+ struct cvmx_mio_fus_dat1_s cn56xxp1;
+ struct cvmx_mio_fus_dat1_s cn58xx;
+ struct cvmx_mio_fus_dat1_s cn58xxp1;
+};
+
+union cvmx_mio_fus_dat2 {
+ uint64_t u64;
+ struct cvmx_mio_fus_dat2_s {
+ uint64_t reserved_34_63:30;
+ uint64_t fus318:1;
+ uint64_t raid_en:1;
+ uint64_t reserved_30_31:2;
+ uint64_t nokasu:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t rst_sht:1;
+ uint64_t bist_dis:1;
+ uint64_t chip_id:8;
+ uint64_t reserved_0_15:16;
+ } s;
+ struct cvmx_mio_fus_dat2_cn30xx {
+ uint64_t reserved_29_63:35;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t rst_sht:1;
+ uint64_t bist_dis:1;
+ uint64_t chip_id:8;
+ uint64_t pll_off:4;
+ uint64_t reserved_1_11:11;
+ uint64_t pp_dis:1;
+ } cn30xx;
+ struct cvmx_mio_fus_dat2_cn31xx {
+ uint64_t reserved_29_63:35;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t rst_sht:1;
+ uint64_t bist_dis:1;
+ uint64_t chip_id:8;
+ uint64_t pll_off:4;
+ uint64_t reserved_2_11:10;
+ uint64_t pp_dis:2;
+ } cn31xx;
+ struct cvmx_mio_fus_dat2_cn38xx {
+ uint64_t reserved_29_63:35;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t rst_sht:1;
+ uint64_t bist_dis:1;
+ uint64_t chip_id:8;
+ uint64_t pp_dis:16;
+ } cn38xx;
+ struct cvmx_mio_fus_dat2_cn38xx cn38xxp2;
+ struct cvmx_mio_fus_dat2_cn50xx {
+ uint64_t reserved_34_63:30;
+ uint64_t fus318:1;
+ uint64_t raid_en:1;
+ uint64_t reserved_30_31:2;
+ uint64_t nokasu:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t rst_sht:1;
+ uint64_t bist_dis:1;
+ uint64_t chip_id:8;
+ uint64_t reserved_2_15:14;
+ uint64_t pp_dis:2;
+ } cn50xx;
+ struct cvmx_mio_fus_dat2_cn52xx {
+ uint64_t reserved_34_63:30;
+ uint64_t fus318:1;
+ uint64_t raid_en:1;
+ uint64_t reserved_30_31:2;
+ uint64_t nokasu:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t rst_sht:1;
+ uint64_t bist_dis:1;
+ uint64_t chip_id:8;
+ uint64_t reserved_4_15:12;
+ uint64_t pp_dis:4;
+ } cn52xx;
+ struct cvmx_mio_fus_dat2_cn52xx cn52xxp1;
+ struct cvmx_mio_fus_dat2_cn56xx {
+ uint64_t reserved_34_63:30;
+ uint64_t fus318:1;
+ uint64_t raid_en:1;
+ uint64_t reserved_30_31:2;
+ uint64_t nokasu:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t rst_sht:1;
+ uint64_t bist_dis:1;
+ uint64_t chip_id:8;
+ uint64_t reserved_12_15:4;
+ uint64_t pp_dis:12;
+ } cn56xx;
+ struct cvmx_mio_fus_dat2_cn56xx cn56xxp1;
+ struct cvmx_mio_fus_dat2_cn58xx {
+ uint64_t reserved_30_63:34;
+ uint64_t nokasu:1;
+ uint64_t nodfa_cp2:1;
+ uint64_t nomul:1;
+ uint64_t nocrypto:1;
+ uint64_t rst_sht:1;
+ uint64_t bist_dis:1;
+ uint64_t chip_id:8;
+ uint64_t pp_dis:16;
+ } cn58xx;
+ struct cvmx_mio_fus_dat2_cn58xx cn58xxp1;
+};
+
+union cvmx_mio_fus_dat3 {
+ uint64_t u64;
+ struct cvmx_mio_fus_dat3_s {
+ uint64_t reserved_32_63:32;
+ uint64_t pll_div4:1;
+ uint64_t zip_crip:2;
+ uint64_t bar2_en:1;
+ uint64_t efus_lck:1;
+ uint64_t efus_ign:1;
+ uint64_t nozip:1;
+ uint64_t nodfa_dte:1;
+ uint64_t icache:24;
+ } s;
+ struct cvmx_mio_fus_dat3_cn30xx {
+ uint64_t reserved_32_63:32;
+ uint64_t pll_div4:1;
+ uint64_t reserved_29_30:2;
+ uint64_t bar2_en:1;
+ uint64_t efus_lck:1;
+ uint64_t efus_ign:1;
+ uint64_t nozip:1;
+ uint64_t nodfa_dte:1;
+ uint64_t icache:24;
+ } cn30xx;
+ struct cvmx_mio_fus_dat3_s cn31xx;
+ struct cvmx_mio_fus_dat3_cn38xx {
+ uint64_t reserved_31_63:33;
+ uint64_t zip_crip:2;
+ uint64_t bar2_en:1;
+ uint64_t efus_lck:1;
+ uint64_t efus_ign:1;
+ uint64_t nozip:1;
+ uint64_t nodfa_dte:1;
+ uint64_t icache:24;
+ } cn38xx;
+ struct cvmx_mio_fus_dat3_cn38xxp2 {
+ uint64_t reserved_29_63:35;
+ uint64_t bar2_en:1;
+ uint64_t efus_lck:1;
+ uint64_t efus_ign:1;
+ uint64_t nozip:1;
+ uint64_t nodfa_dte:1;
+ uint64_t icache:24;
+ } cn38xxp2;
+ struct cvmx_mio_fus_dat3_cn38xx cn50xx;
+ struct cvmx_mio_fus_dat3_cn38xx cn52xx;
+ struct cvmx_mio_fus_dat3_cn38xx cn52xxp1;
+ struct cvmx_mio_fus_dat3_cn38xx cn56xx;
+ struct cvmx_mio_fus_dat3_cn38xx cn56xxp1;
+ struct cvmx_mio_fus_dat3_cn38xx cn58xx;
+ struct cvmx_mio_fus_dat3_cn38xx cn58xxp1;
+};
+
+union cvmx_mio_fus_ema {
+ uint64_t u64;
+ struct cvmx_mio_fus_ema_s {
+ uint64_t reserved_7_63:57;
+ uint64_t eff_ema:3;
+ uint64_t reserved_3_3:1;
+ uint64_t ema:3;
+ } s;
+ struct cvmx_mio_fus_ema_s cn50xx;
+ struct cvmx_mio_fus_ema_s cn52xx;
+ struct cvmx_mio_fus_ema_s cn52xxp1;
+ struct cvmx_mio_fus_ema_s cn56xx;
+ struct cvmx_mio_fus_ema_s cn56xxp1;
+ struct cvmx_mio_fus_ema_cn58xx {
+ uint64_t reserved_2_63:62;
+ uint64_t ema:2;
+ } cn58xx;
+ struct cvmx_mio_fus_ema_cn58xx cn58xxp1;
+};
+
+union cvmx_mio_fus_pdf {
+ uint64_t u64;
+ struct cvmx_mio_fus_pdf_s {
+ uint64_t pdf:64;
+ } s;
+ struct cvmx_mio_fus_pdf_s cn50xx;
+ struct cvmx_mio_fus_pdf_s cn52xx;
+ struct cvmx_mio_fus_pdf_s cn52xxp1;
+ struct cvmx_mio_fus_pdf_s cn56xx;
+ struct cvmx_mio_fus_pdf_s cn56xxp1;
+ struct cvmx_mio_fus_pdf_s cn58xx;
+};
+
+union cvmx_mio_fus_pll {
+ uint64_t u64;
+ struct cvmx_mio_fus_pll_s {
+ uint64_t reserved_2_63:62;
+ uint64_t rfslip:1;
+ uint64_t fbslip:1;
+ } s;
+ struct cvmx_mio_fus_pll_s cn50xx;
+ struct cvmx_mio_fus_pll_s cn52xx;
+ struct cvmx_mio_fus_pll_s cn52xxp1;
+ struct cvmx_mio_fus_pll_s cn56xx;
+ struct cvmx_mio_fus_pll_s cn56xxp1;
+ struct cvmx_mio_fus_pll_s cn58xx;
+ struct cvmx_mio_fus_pll_s cn58xxp1;
+};
+
+union cvmx_mio_fus_prog {
+ uint64_t u64;
+ struct cvmx_mio_fus_prog_s {
+ uint64_t reserved_1_63:63;
+ uint64_t prog:1;
+ } s;
+ struct cvmx_mio_fus_prog_s cn30xx;
+ struct cvmx_mio_fus_prog_s cn31xx;
+ struct cvmx_mio_fus_prog_s cn38xx;
+ struct cvmx_mio_fus_prog_s cn38xxp2;
+ struct cvmx_mio_fus_prog_s cn50xx;
+ struct cvmx_mio_fus_prog_s cn52xx;
+ struct cvmx_mio_fus_prog_s cn52xxp1;
+ struct cvmx_mio_fus_prog_s cn56xx;
+ struct cvmx_mio_fus_prog_s cn56xxp1;
+ struct cvmx_mio_fus_prog_s cn58xx;
+ struct cvmx_mio_fus_prog_s cn58xxp1;
+};
+
+union cvmx_mio_fus_prog_times {
+ uint64_t u64;
+ struct cvmx_mio_fus_prog_times_s {
+ uint64_t reserved_33_63:31;
+ uint64_t prog_pin:1;
+ uint64_t out:8;
+ uint64_t sclk_lo:4;
+ uint64_t sclk_hi:12;
+ uint64_t setup:8;
+ } s;
+ struct cvmx_mio_fus_prog_times_s cn50xx;
+ struct cvmx_mio_fus_prog_times_s cn52xx;
+ struct cvmx_mio_fus_prog_times_s cn52xxp1;
+ struct cvmx_mio_fus_prog_times_s cn56xx;
+ struct cvmx_mio_fus_prog_times_s cn56xxp1;
+ struct cvmx_mio_fus_prog_times_s cn58xx;
+ struct cvmx_mio_fus_prog_times_s cn58xxp1;
+};
+
+union cvmx_mio_fus_rcmd {
+ uint64_t u64;
+ struct cvmx_mio_fus_rcmd_s {
+ uint64_t reserved_24_63:40;
+ uint64_t dat:8;
+ uint64_t reserved_13_15:3;
+ uint64_t pend:1;
+ uint64_t reserved_9_11:3;
+ uint64_t efuse:1;
+ uint64_t addr:8;
+ } s;
+ struct cvmx_mio_fus_rcmd_cn30xx {
+ uint64_t reserved_24_63:40;
+ uint64_t dat:8;
+ uint64_t reserved_13_15:3;
+ uint64_t pend:1;
+ uint64_t reserved_9_11:3;
+ uint64_t efuse:1;
+ uint64_t reserved_7_7:1;
+ uint64_t addr:7;
+ } cn30xx;
+ struct cvmx_mio_fus_rcmd_cn30xx cn31xx;
+ struct cvmx_mio_fus_rcmd_cn30xx cn38xx;
+ struct cvmx_mio_fus_rcmd_cn30xx cn38xxp2;
+ struct cvmx_mio_fus_rcmd_cn30xx cn50xx;
+ struct cvmx_mio_fus_rcmd_s cn52xx;
+ struct cvmx_mio_fus_rcmd_s cn52xxp1;
+ struct cvmx_mio_fus_rcmd_s cn56xx;
+ struct cvmx_mio_fus_rcmd_s cn56xxp1;
+ struct cvmx_mio_fus_rcmd_cn30xx cn58xx;
+ struct cvmx_mio_fus_rcmd_cn30xx cn58xxp1;
+};
+
+union cvmx_mio_fus_spr_repair_res {
+ uint64_t u64;
+ struct cvmx_mio_fus_spr_repair_res_s {
+ uint64_t reserved_42_63:22;
+ uint64_t repair2:14;
+ uint64_t repair1:14;
+ uint64_t repair0:14;
+ } s;
+ struct cvmx_mio_fus_spr_repair_res_s cn30xx;
+ struct cvmx_mio_fus_spr_repair_res_s cn31xx;
+ struct cvmx_mio_fus_spr_repair_res_s cn38xx;
+ struct cvmx_mio_fus_spr_repair_res_s cn50xx;
+ struct cvmx_mio_fus_spr_repair_res_s cn52xx;
+ struct cvmx_mio_fus_spr_repair_res_s cn52xxp1;
+ struct cvmx_mio_fus_spr_repair_res_s cn56xx;
+ struct cvmx_mio_fus_spr_repair_res_s cn56xxp1;
+ struct cvmx_mio_fus_spr_repair_res_s cn58xx;
+ struct cvmx_mio_fus_spr_repair_res_s cn58xxp1;
+};
+
+union cvmx_mio_fus_spr_repair_sum {
+ uint64_t u64;
+ struct cvmx_mio_fus_spr_repair_sum_s {
+ uint64_t reserved_1_63:63;
+ uint64_t too_many:1;
+ } s;
+ struct cvmx_mio_fus_spr_repair_sum_s cn30xx;
+ struct cvmx_mio_fus_spr_repair_sum_s cn31xx;
+ struct cvmx_mio_fus_spr_repair_sum_s cn38xx;
+ struct cvmx_mio_fus_spr_repair_sum_s cn50xx;
+ struct cvmx_mio_fus_spr_repair_sum_s cn52xx;
+ struct cvmx_mio_fus_spr_repair_sum_s cn52xxp1;
+ struct cvmx_mio_fus_spr_repair_sum_s cn56xx;
+ struct cvmx_mio_fus_spr_repair_sum_s cn56xxp1;
+ struct cvmx_mio_fus_spr_repair_sum_s cn58xx;
+ struct cvmx_mio_fus_spr_repair_sum_s cn58xxp1;
+};
+
+union cvmx_mio_fus_unlock {
+ uint64_t u64;
+ struct cvmx_mio_fus_unlock_s {
+ uint64_t reserved_24_63:40;
+ uint64_t key:24;
+ } s;
+ struct cvmx_mio_fus_unlock_s cn30xx;
+ struct cvmx_mio_fus_unlock_s cn31xx;
+};
+
+union cvmx_mio_fus_wadr {
+ uint64_t u64;
+ struct cvmx_mio_fus_wadr_s {
+ uint64_t reserved_10_63:54;
+ uint64_t addr:10;
+ } s;
+ struct cvmx_mio_fus_wadr_s cn30xx;
+ struct cvmx_mio_fus_wadr_s cn31xx;
+ struct cvmx_mio_fus_wadr_s cn38xx;
+ struct cvmx_mio_fus_wadr_s cn38xxp2;
+ struct cvmx_mio_fus_wadr_cn50xx {
+ uint64_t reserved_2_63:62;
+ uint64_t addr:2;
+ } cn50xx;
+ struct cvmx_mio_fus_wadr_cn52xx {
+ uint64_t reserved_3_63:61;
+ uint64_t addr:3;
+ } cn52xx;
+ struct cvmx_mio_fus_wadr_cn52xx cn52xxp1;
+ struct cvmx_mio_fus_wadr_cn52xx cn56xx;
+ struct cvmx_mio_fus_wadr_cn52xx cn56xxp1;
+ struct cvmx_mio_fus_wadr_cn50xx cn58xx;
+ struct cvmx_mio_fus_wadr_cn50xx cn58xxp1;
+};
+
+union cvmx_mio_ndf_dma_cfg {
+ uint64_t u64;
+ struct cvmx_mio_ndf_dma_cfg_s {
+ uint64_t en:1;
+ uint64_t rw:1;
+ uint64_t clr:1;
+ uint64_t reserved_60_60:1;
+ uint64_t swap32:1;
+ uint64_t swap16:1;
+ uint64_t swap8:1;
+ uint64_t endian:1;
+ uint64_t size:20;
+ uint64_t adr:36;
+ } s;
+ struct cvmx_mio_ndf_dma_cfg_s cn52xx;
+};
+
+union cvmx_mio_ndf_dma_int {
+ uint64_t u64;
+ struct cvmx_mio_ndf_dma_int_s {
+ uint64_t reserved_1_63:63;
+ uint64_t done:1;
+ } s;
+ struct cvmx_mio_ndf_dma_int_s cn52xx;
+};
+
+union cvmx_mio_ndf_dma_int_en {
+ uint64_t u64;
+ struct cvmx_mio_ndf_dma_int_en_s {
+ uint64_t reserved_1_63:63;
+ uint64_t done:1;
+ } s;
+ struct cvmx_mio_ndf_dma_int_en_s cn52xx;
+};
+
+union cvmx_mio_pll_ctl {
+ uint64_t u64;
+ struct cvmx_mio_pll_ctl_s {
+ uint64_t reserved_5_63:59;
+ uint64_t bw_ctl:5;
+ } s;
+ struct cvmx_mio_pll_ctl_s cn30xx;
+ struct cvmx_mio_pll_ctl_s cn31xx;
+};
+
+union cvmx_mio_pll_setting {
+ uint64_t u64;
+ struct cvmx_mio_pll_setting_s {
+ uint64_t reserved_17_63:47;
+ uint64_t setting:17;
+ } s;
+ struct cvmx_mio_pll_setting_s cn30xx;
+ struct cvmx_mio_pll_setting_s cn31xx;
+};
+
+union cvmx_mio_twsx_int {
+ uint64_t u64;
+ struct cvmx_mio_twsx_int_s {
+ uint64_t reserved_12_63:52;
+ uint64_t scl:1;
+ uint64_t sda:1;
+ uint64_t scl_ovr:1;
+ uint64_t sda_ovr:1;
+ uint64_t reserved_7_7:1;
+ uint64_t core_en:1;
+ uint64_t ts_en:1;
+ uint64_t st_en:1;
+ uint64_t reserved_3_3:1;
+ uint64_t core_int:1;
+ uint64_t ts_int:1;
+ uint64_t st_int:1;
+ } s;
+ struct cvmx_mio_twsx_int_s cn30xx;
+ struct cvmx_mio_twsx_int_s cn31xx;
+ struct cvmx_mio_twsx_int_s cn38xx;
+ struct cvmx_mio_twsx_int_cn38xxp2 {
+ uint64_t reserved_7_63:57;
+ uint64_t core_en:1;
+ uint64_t ts_en:1;
+ uint64_t st_en:1;
+ uint64_t reserved_3_3:1;
+ uint64_t core_int:1;
+ uint64_t ts_int:1;
+ uint64_t st_int:1;
+ } cn38xxp2;
+ struct cvmx_mio_twsx_int_s cn50xx;
+ struct cvmx_mio_twsx_int_s cn52xx;
+ struct cvmx_mio_twsx_int_s cn52xxp1;
+ struct cvmx_mio_twsx_int_s cn56xx;
+ struct cvmx_mio_twsx_int_s cn56xxp1;
+ struct cvmx_mio_twsx_int_s cn58xx;
+ struct cvmx_mio_twsx_int_s cn58xxp1;
+};
+
+union cvmx_mio_twsx_sw_twsi {
+ uint64_t u64;
+ struct cvmx_mio_twsx_sw_twsi_s {
+ uint64_t v:1;
+ uint64_t slonly:1;
+ uint64_t eia:1;
+ uint64_t op:4;
+ uint64_t r:1;
+ uint64_t sovr:1;
+ uint64_t size:3;
+ uint64_t scr:2;
+ uint64_t a:10;
+ uint64_t ia:5;
+ uint64_t eop_ia:3;
+ uint64_t d:32;
+ } s;
+ struct cvmx_mio_twsx_sw_twsi_s cn30xx;
+ struct cvmx_mio_twsx_sw_twsi_s cn31xx;
+ struct cvmx_mio_twsx_sw_twsi_s cn38xx;
+ struct cvmx_mio_twsx_sw_twsi_s cn38xxp2;
+ struct cvmx_mio_twsx_sw_twsi_s cn50xx;
+ struct cvmx_mio_twsx_sw_twsi_s cn52xx;
+ struct cvmx_mio_twsx_sw_twsi_s cn52xxp1;
+ struct cvmx_mio_twsx_sw_twsi_s cn56xx;
+ struct cvmx_mio_twsx_sw_twsi_s cn56xxp1;
+ struct cvmx_mio_twsx_sw_twsi_s cn58xx;
+ struct cvmx_mio_twsx_sw_twsi_s cn58xxp1;
+};
+
+union cvmx_mio_twsx_sw_twsi_ext {
+ uint64_t u64;
+ struct cvmx_mio_twsx_sw_twsi_ext_s {
+ uint64_t reserved_40_63:24;
+ uint64_t ia:8;
+ uint64_t d:32;
+ } s;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn30xx;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn31xx;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn38xx;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn38xxp2;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn50xx;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn52xx;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn52xxp1;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn56xx;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn56xxp1;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn58xx;
+ struct cvmx_mio_twsx_sw_twsi_ext_s cn58xxp1;
+};
+
+union cvmx_mio_twsx_twsi_sw {
+ uint64_t u64;
+ struct cvmx_mio_twsx_twsi_sw_s {
+ uint64_t v:2;
+ uint64_t reserved_32_61:30;
+ uint64_t d:32;
+ } s;
+ struct cvmx_mio_twsx_twsi_sw_s cn30xx;
+ struct cvmx_mio_twsx_twsi_sw_s cn31xx;
+ struct cvmx_mio_twsx_twsi_sw_s cn38xx;
+ struct cvmx_mio_twsx_twsi_sw_s cn38xxp2;
+ struct cvmx_mio_twsx_twsi_sw_s cn50xx;
+ struct cvmx_mio_twsx_twsi_sw_s cn52xx;
+ struct cvmx_mio_twsx_twsi_sw_s cn52xxp1;
+ struct cvmx_mio_twsx_twsi_sw_s cn56xx;
+ struct cvmx_mio_twsx_twsi_sw_s cn56xxp1;
+ struct cvmx_mio_twsx_twsi_sw_s cn58xx;
+ struct cvmx_mio_twsx_twsi_sw_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_dlh {
+ uint64_t u64;
+ struct cvmx_mio_uartx_dlh_s {
+ uint64_t reserved_8_63:56;
+ uint64_t dlh:8;
+ } s;
+ struct cvmx_mio_uartx_dlh_s cn30xx;
+ struct cvmx_mio_uartx_dlh_s cn31xx;
+ struct cvmx_mio_uartx_dlh_s cn38xx;
+ struct cvmx_mio_uartx_dlh_s cn38xxp2;
+ struct cvmx_mio_uartx_dlh_s cn50xx;
+ struct cvmx_mio_uartx_dlh_s cn52xx;
+ struct cvmx_mio_uartx_dlh_s cn52xxp1;
+ struct cvmx_mio_uartx_dlh_s cn56xx;
+ struct cvmx_mio_uartx_dlh_s cn56xxp1;
+ struct cvmx_mio_uartx_dlh_s cn58xx;
+ struct cvmx_mio_uartx_dlh_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_dll {
+ uint64_t u64;
+ struct cvmx_mio_uartx_dll_s {
+ uint64_t reserved_8_63:56;
+ uint64_t dll:8;
+ } s;
+ struct cvmx_mio_uartx_dll_s cn30xx;
+ struct cvmx_mio_uartx_dll_s cn31xx;
+ struct cvmx_mio_uartx_dll_s cn38xx;
+ struct cvmx_mio_uartx_dll_s cn38xxp2;
+ struct cvmx_mio_uartx_dll_s cn50xx;
+ struct cvmx_mio_uartx_dll_s cn52xx;
+ struct cvmx_mio_uartx_dll_s cn52xxp1;
+ struct cvmx_mio_uartx_dll_s cn56xx;
+ struct cvmx_mio_uartx_dll_s cn56xxp1;
+ struct cvmx_mio_uartx_dll_s cn58xx;
+ struct cvmx_mio_uartx_dll_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_far {
+ uint64_t u64;
+ struct cvmx_mio_uartx_far_s {
+ uint64_t reserved_1_63:63;
+ uint64_t far:1;
+ } s;
+ struct cvmx_mio_uartx_far_s cn30xx;
+ struct cvmx_mio_uartx_far_s cn31xx;
+ struct cvmx_mio_uartx_far_s cn38xx;
+ struct cvmx_mio_uartx_far_s cn38xxp2;
+ struct cvmx_mio_uartx_far_s cn50xx;
+ struct cvmx_mio_uartx_far_s cn52xx;
+ struct cvmx_mio_uartx_far_s cn52xxp1;
+ struct cvmx_mio_uartx_far_s cn56xx;
+ struct cvmx_mio_uartx_far_s cn56xxp1;
+ struct cvmx_mio_uartx_far_s cn58xx;
+ struct cvmx_mio_uartx_far_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_fcr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_fcr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t rxtrig:2;
+ uint64_t txtrig:2;
+ uint64_t reserved_3_3:1;
+ uint64_t txfr:1;
+ uint64_t rxfr:1;
+ uint64_t en:1;
+ } s;
+ struct cvmx_mio_uartx_fcr_s cn30xx;
+ struct cvmx_mio_uartx_fcr_s cn31xx;
+ struct cvmx_mio_uartx_fcr_s cn38xx;
+ struct cvmx_mio_uartx_fcr_s cn38xxp2;
+ struct cvmx_mio_uartx_fcr_s cn50xx;
+ struct cvmx_mio_uartx_fcr_s cn52xx;
+ struct cvmx_mio_uartx_fcr_s cn52xxp1;
+ struct cvmx_mio_uartx_fcr_s cn56xx;
+ struct cvmx_mio_uartx_fcr_s cn56xxp1;
+ struct cvmx_mio_uartx_fcr_s cn58xx;
+ struct cvmx_mio_uartx_fcr_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_htx {
+ uint64_t u64;
+ struct cvmx_mio_uartx_htx_s {
+ uint64_t reserved_1_63:63;
+ uint64_t htx:1;
+ } s;
+ struct cvmx_mio_uartx_htx_s cn30xx;
+ struct cvmx_mio_uartx_htx_s cn31xx;
+ struct cvmx_mio_uartx_htx_s cn38xx;
+ struct cvmx_mio_uartx_htx_s cn38xxp2;
+ struct cvmx_mio_uartx_htx_s cn50xx;
+ struct cvmx_mio_uartx_htx_s cn52xx;
+ struct cvmx_mio_uartx_htx_s cn52xxp1;
+ struct cvmx_mio_uartx_htx_s cn56xx;
+ struct cvmx_mio_uartx_htx_s cn56xxp1;
+ struct cvmx_mio_uartx_htx_s cn58xx;
+ struct cvmx_mio_uartx_htx_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_ier {
+ uint64_t u64;
+ struct cvmx_mio_uartx_ier_s {
+ uint64_t reserved_8_63:56;
+ uint64_t ptime:1;
+ uint64_t reserved_4_6:3;
+ uint64_t edssi:1;
+ uint64_t elsi:1;
+ uint64_t etbei:1;
+ uint64_t erbfi:1;
+ } s;
+ struct cvmx_mio_uartx_ier_s cn30xx;
+ struct cvmx_mio_uartx_ier_s cn31xx;
+ struct cvmx_mio_uartx_ier_s cn38xx;
+ struct cvmx_mio_uartx_ier_s cn38xxp2;
+ struct cvmx_mio_uartx_ier_s cn50xx;
+ struct cvmx_mio_uartx_ier_s cn52xx;
+ struct cvmx_mio_uartx_ier_s cn52xxp1;
+ struct cvmx_mio_uartx_ier_s cn56xx;
+ struct cvmx_mio_uartx_ier_s cn56xxp1;
+ struct cvmx_mio_uartx_ier_s cn58xx;
+ struct cvmx_mio_uartx_ier_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_iir {
+ uint64_t u64;
+ struct cvmx_mio_uartx_iir_s {
+ uint64_t reserved_8_63:56;
+ uint64_t fen:2;
+ uint64_t reserved_4_5:2;
+ uint64_t iid:4;
+ } s;
+ struct cvmx_mio_uartx_iir_s cn30xx;
+ struct cvmx_mio_uartx_iir_s cn31xx;
+ struct cvmx_mio_uartx_iir_s cn38xx;
+ struct cvmx_mio_uartx_iir_s cn38xxp2;
+ struct cvmx_mio_uartx_iir_s cn50xx;
+ struct cvmx_mio_uartx_iir_s cn52xx;
+ struct cvmx_mio_uartx_iir_s cn52xxp1;
+ struct cvmx_mio_uartx_iir_s cn56xx;
+ struct cvmx_mio_uartx_iir_s cn56xxp1;
+ struct cvmx_mio_uartx_iir_s cn58xx;
+ struct cvmx_mio_uartx_iir_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_lcr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_lcr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t dlab:1;
+ uint64_t brk:1;
+ uint64_t reserved_5_5:1;
+ uint64_t eps:1;
+ uint64_t pen:1;
+ uint64_t stop:1;
+ uint64_t cls:2;
+ } s;
+ struct cvmx_mio_uartx_lcr_s cn30xx;
+ struct cvmx_mio_uartx_lcr_s cn31xx;
+ struct cvmx_mio_uartx_lcr_s cn38xx;
+ struct cvmx_mio_uartx_lcr_s cn38xxp2;
+ struct cvmx_mio_uartx_lcr_s cn50xx;
+ struct cvmx_mio_uartx_lcr_s cn52xx;
+ struct cvmx_mio_uartx_lcr_s cn52xxp1;
+ struct cvmx_mio_uartx_lcr_s cn56xx;
+ struct cvmx_mio_uartx_lcr_s cn56xxp1;
+ struct cvmx_mio_uartx_lcr_s cn58xx;
+ struct cvmx_mio_uartx_lcr_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_lsr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_lsr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t ferr:1;
+ uint64_t temt:1;
+ uint64_t thre:1;
+ uint64_t bi:1;
+ uint64_t fe:1;
+ uint64_t pe:1;
+ uint64_t oe:1;
+ uint64_t dr:1;
+ } s;
+ struct cvmx_mio_uartx_lsr_s cn30xx;
+ struct cvmx_mio_uartx_lsr_s cn31xx;
+ struct cvmx_mio_uartx_lsr_s cn38xx;
+ struct cvmx_mio_uartx_lsr_s cn38xxp2;
+ struct cvmx_mio_uartx_lsr_s cn50xx;
+ struct cvmx_mio_uartx_lsr_s cn52xx;
+ struct cvmx_mio_uartx_lsr_s cn52xxp1;
+ struct cvmx_mio_uartx_lsr_s cn56xx;
+ struct cvmx_mio_uartx_lsr_s cn56xxp1;
+ struct cvmx_mio_uartx_lsr_s cn58xx;
+ struct cvmx_mio_uartx_lsr_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_mcr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_mcr_s {
+ uint64_t reserved_6_63:58;
+ uint64_t afce:1;
+ uint64_t loop:1;
+ uint64_t out2:1;
+ uint64_t out1:1;
+ uint64_t rts:1;
+ uint64_t dtr:1;
+ } s;
+ struct cvmx_mio_uartx_mcr_s cn30xx;
+ struct cvmx_mio_uartx_mcr_s cn31xx;
+ struct cvmx_mio_uartx_mcr_s cn38xx;
+ struct cvmx_mio_uartx_mcr_s cn38xxp2;
+ struct cvmx_mio_uartx_mcr_s cn50xx;
+ struct cvmx_mio_uartx_mcr_s cn52xx;
+ struct cvmx_mio_uartx_mcr_s cn52xxp1;
+ struct cvmx_mio_uartx_mcr_s cn56xx;
+ struct cvmx_mio_uartx_mcr_s cn56xxp1;
+ struct cvmx_mio_uartx_mcr_s cn58xx;
+ struct cvmx_mio_uartx_mcr_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_msr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_msr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t dcd:1;
+ uint64_t ri:1;
+ uint64_t dsr:1;
+ uint64_t cts:1;
+ uint64_t ddcd:1;
+ uint64_t teri:1;
+ uint64_t ddsr:1;
+ uint64_t dcts:1;
+ } s;
+ struct cvmx_mio_uartx_msr_s cn30xx;
+ struct cvmx_mio_uartx_msr_s cn31xx;
+ struct cvmx_mio_uartx_msr_s cn38xx;
+ struct cvmx_mio_uartx_msr_s cn38xxp2;
+ struct cvmx_mio_uartx_msr_s cn50xx;
+ struct cvmx_mio_uartx_msr_s cn52xx;
+ struct cvmx_mio_uartx_msr_s cn52xxp1;
+ struct cvmx_mio_uartx_msr_s cn56xx;
+ struct cvmx_mio_uartx_msr_s cn56xxp1;
+ struct cvmx_mio_uartx_msr_s cn58xx;
+ struct cvmx_mio_uartx_msr_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_rbr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_rbr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t rbr:8;
+ } s;
+ struct cvmx_mio_uartx_rbr_s cn30xx;
+ struct cvmx_mio_uartx_rbr_s cn31xx;
+ struct cvmx_mio_uartx_rbr_s cn38xx;
+ struct cvmx_mio_uartx_rbr_s cn38xxp2;
+ struct cvmx_mio_uartx_rbr_s cn50xx;
+ struct cvmx_mio_uartx_rbr_s cn52xx;
+ struct cvmx_mio_uartx_rbr_s cn52xxp1;
+ struct cvmx_mio_uartx_rbr_s cn56xx;
+ struct cvmx_mio_uartx_rbr_s cn56xxp1;
+ struct cvmx_mio_uartx_rbr_s cn58xx;
+ struct cvmx_mio_uartx_rbr_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_rfl {
+ uint64_t u64;
+ struct cvmx_mio_uartx_rfl_s {
+ uint64_t reserved_7_63:57;
+ uint64_t rfl:7;
+ } s;
+ struct cvmx_mio_uartx_rfl_s cn30xx;
+ struct cvmx_mio_uartx_rfl_s cn31xx;
+ struct cvmx_mio_uartx_rfl_s cn38xx;
+ struct cvmx_mio_uartx_rfl_s cn38xxp2;
+ struct cvmx_mio_uartx_rfl_s cn50xx;
+ struct cvmx_mio_uartx_rfl_s cn52xx;
+ struct cvmx_mio_uartx_rfl_s cn52xxp1;
+ struct cvmx_mio_uartx_rfl_s cn56xx;
+ struct cvmx_mio_uartx_rfl_s cn56xxp1;
+ struct cvmx_mio_uartx_rfl_s cn58xx;
+ struct cvmx_mio_uartx_rfl_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_rfw {
+ uint64_t u64;
+ struct cvmx_mio_uartx_rfw_s {
+ uint64_t reserved_10_63:54;
+ uint64_t rffe:1;
+ uint64_t rfpe:1;
+ uint64_t rfwd:8;
+ } s;
+ struct cvmx_mio_uartx_rfw_s cn30xx;
+ struct cvmx_mio_uartx_rfw_s cn31xx;
+ struct cvmx_mio_uartx_rfw_s cn38xx;
+ struct cvmx_mio_uartx_rfw_s cn38xxp2;
+ struct cvmx_mio_uartx_rfw_s cn50xx;
+ struct cvmx_mio_uartx_rfw_s cn52xx;
+ struct cvmx_mio_uartx_rfw_s cn52xxp1;
+ struct cvmx_mio_uartx_rfw_s cn56xx;
+ struct cvmx_mio_uartx_rfw_s cn56xxp1;
+ struct cvmx_mio_uartx_rfw_s cn58xx;
+ struct cvmx_mio_uartx_rfw_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_sbcr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_sbcr_s {
+ uint64_t reserved_1_63:63;
+ uint64_t sbcr:1;
+ } s;
+ struct cvmx_mio_uartx_sbcr_s cn30xx;
+ struct cvmx_mio_uartx_sbcr_s cn31xx;
+ struct cvmx_mio_uartx_sbcr_s cn38xx;
+ struct cvmx_mio_uartx_sbcr_s cn38xxp2;
+ struct cvmx_mio_uartx_sbcr_s cn50xx;
+ struct cvmx_mio_uartx_sbcr_s cn52xx;
+ struct cvmx_mio_uartx_sbcr_s cn52xxp1;
+ struct cvmx_mio_uartx_sbcr_s cn56xx;
+ struct cvmx_mio_uartx_sbcr_s cn56xxp1;
+ struct cvmx_mio_uartx_sbcr_s cn58xx;
+ struct cvmx_mio_uartx_sbcr_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_scr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_scr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t scr:8;
+ } s;
+ struct cvmx_mio_uartx_scr_s cn30xx;
+ struct cvmx_mio_uartx_scr_s cn31xx;
+ struct cvmx_mio_uartx_scr_s cn38xx;
+ struct cvmx_mio_uartx_scr_s cn38xxp2;
+ struct cvmx_mio_uartx_scr_s cn50xx;
+ struct cvmx_mio_uartx_scr_s cn52xx;
+ struct cvmx_mio_uartx_scr_s cn52xxp1;
+ struct cvmx_mio_uartx_scr_s cn56xx;
+ struct cvmx_mio_uartx_scr_s cn56xxp1;
+ struct cvmx_mio_uartx_scr_s cn58xx;
+ struct cvmx_mio_uartx_scr_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_sfe {
+ uint64_t u64;
+ struct cvmx_mio_uartx_sfe_s {
+ uint64_t reserved_1_63:63;
+ uint64_t sfe:1;
+ } s;
+ struct cvmx_mio_uartx_sfe_s cn30xx;
+ struct cvmx_mio_uartx_sfe_s cn31xx;
+ struct cvmx_mio_uartx_sfe_s cn38xx;
+ struct cvmx_mio_uartx_sfe_s cn38xxp2;
+ struct cvmx_mio_uartx_sfe_s cn50xx;
+ struct cvmx_mio_uartx_sfe_s cn52xx;
+ struct cvmx_mio_uartx_sfe_s cn52xxp1;
+ struct cvmx_mio_uartx_sfe_s cn56xx;
+ struct cvmx_mio_uartx_sfe_s cn56xxp1;
+ struct cvmx_mio_uartx_sfe_s cn58xx;
+ struct cvmx_mio_uartx_sfe_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_srr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_srr_s {
+ uint64_t reserved_3_63:61;
+ uint64_t stfr:1;
+ uint64_t srfr:1;
+ uint64_t usr:1;
+ } s;
+ struct cvmx_mio_uartx_srr_s cn30xx;
+ struct cvmx_mio_uartx_srr_s cn31xx;
+ struct cvmx_mio_uartx_srr_s cn38xx;
+ struct cvmx_mio_uartx_srr_s cn38xxp2;
+ struct cvmx_mio_uartx_srr_s cn50xx;
+ struct cvmx_mio_uartx_srr_s cn52xx;
+ struct cvmx_mio_uartx_srr_s cn52xxp1;
+ struct cvmx_mio_uartx_srr_s cn56xx;
+ struct cvmx_mio_uartx_srr_s cn56xxp1;
+ struct cvmx_mio_uartx_srr_s cn58xx;
+ struct cvmx_mio_uartx_srr_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_srt {
+ uint64_t u64;
+ struct cvmx_mio_uartx_srt_s {
+ uint64_t reserved_2_63:62;
+ uint64_t srt:2;
+ } s;
+ struct cvmx_mio_uartx_srt_s cn30xx;
+ struct cvmx_mio_uartx_srt_s cn31xx;
+ struct cvmx_mio_uartx_srt_s cn38xx;
+ struct cvmx_mio_uartx_srt_s cn38xxp2;
+ struct cvmx_mio_uartx_srt_s cn50xx;
+ struct cvmx_mio_uartx_srt_s cn52xx;
+ struct cvmx_mio_uartx_srt_s cn52xxp1;
+ struct cvmx_mio_uartx_srt_s cn56xx;
+ struct cvmx_mio_uartx_srt_s cn56xxp1;
+ struct cvmx_mio_uartx_srt_s cn58xx;
+ struct cvmx_mio_uartx_srt_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_srts {
+ uint64_t u64;
+ struct cvmx_mio_uartx_srts_s {
+ uint64_t reserved_1_63:63;
+ uint64_t srts:1;
+ } s;
+ struct cvmx_mio_uartx_srts_s cn30xx;
+ struct cvmx_mio_uartx_srts_s cn31xx;
+ struct cvmx_mio_uartx_srts_s cn38xx;
+ struct cvmx_mio_uartx_srts_s cn38xxp2;
+ struct cvmx_mio_uartx_srts_s cn50xx;
+ struct cvmx_mio_uartx_srts_s cn52xx;
+ struct cvmx_mio_uartx_srts_s cn52xxp1;
+ struct cvmx_mio_uartx_srts_s cn56xx;
+ struct cvmx_mio_uartx_srts_s cn56xxp1;
+ struct cvmx_mio_uartx_srts_s cn58xx;
+ struct cvmx_mio_uartx_srts_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_stt {
+ uint64_t u64;
+ struct cvmx_mio_uartx_stt_s {
+ uint64_t reserved_2_63:62;
+ uint64_t stt:2;
+ } s;
+ struct cvmx_mio_uartx_stt_s cn30xx;
+ struct cvmx_mio_uartx_stt_s cn31xx;
+ struct cvmx_mio_uartx_stt_s cn38xx;
+ struct cvmx_mio_uartx_stt_s cn38xxp2;
+ struct cvmx_mio_uartx_stt_s cn50xx;
+ struct cvmx_mio_uartx_stt_s cn52xx;
+ struct cvmx_mio_uartx_stt_s cn52xxp1;
+ struct cvmx_mio_uartx_stt_s cn56xx;
+ struct cvmx_mio_uartx_stt_s cn56xxp1;
+ struct cvmx_mio_uartx_stt_s cn58xx;
+ struct cvmx_mio_uartx_stt_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_tfl {
+ uint64_t u64;
+ struct cvmx_mio_uartx_tfl_s {
+ uint64_t reserved_7_63:57;
+ uint64_t tfl:7;
+ } s;
+ struct cvmx_mio_uartx_tfl_s cn30xx;
+ struct cvmx_mio_uartx_tfl_s cn31xx;
+ struct cvmx_mio_uartx_tfl_s cn38xx;
+ struct cvmx_mio_uartx_tfl_s cn38xxp2;
+ struct cvmx_mio_uartx_tfl_s cn50xx;
+ struct cvmx_mio_uartx_tfl_s cn52xx;
+ struct cvmx_mio_uartx_tfl_s cn52xxp1;
+ struct cvmx_mio_uartx_tfl_s cn56xx;
+ struct cvmx_mio_uartx_tfl_s cn56xxp1;
+ struct cvmx_mio_uartx_tfl_s cn58xx;
+ struct cvmx_mio_uartx_tfl_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_tfr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_tfr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t tfr:8;
+ } s;
+ struct cvmx_mio_uartx_tfr_s cn30xx;
+ struct cvmx_mio_uartx_tfr_s cn31xx;
+ struct cvmx_mio_uartx_tfr_s cn38xx;
+ struct cvmx_mio_uartx_tfr_s cn38xxp2;
+ struct cvmx_mio_uartx_tfr_s cn50xx;
+ struct cvmx_mio_uartx_tfr_s cn52xx;
+ struct cvmx_mio_uartx_tfr_s cn52xxp1;
+ struct cvmx_mio_uartx_tfr_s cn56xx;
+ struct cvmx_mio_uartx_tfr_s cn56xxp1;
+ struct cvmx_mio_uartx_tfr_s cn58xx;
+ struct cvmx_mio_uartx_tfr_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_thr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_thr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t thr:8;
+ } s;
+ struct cvmx_mio_uartx_thr_s cn30xx;
+ struct cvmx_mio_uartx_thr_s cn31xx;
+ struct cvmx_mio_uartx_thr_s cn38xx;
+ struct cvmx_mio_uartx_thr_s cn38xxp2;
+ struct cvmx_mio_uartx_thr_s cn50xx;
+ struct cvmx_mio_uartx_thr_s cn52xx;
+ struct cvmx_mio_uartx_thr_s cn52xxp1;
+ struct cvmx_mio_uartx_thr_s cn56xx;
+ struct cvmx_mio_uartx_thr_s cn56xxp1;
+ struct cvmx_mio_uartx_thr_s cn58xx;
+ struct cvmx_mio_uartx_thr_s cn58xxp1;
+};
+
+union cvmx_mio_uartx_usr {
+ uint64_t u64;
+ struct cvmx_mio_uartx_usr_s {
+ uint64_t reserved_5_63:59;
+ uint64_t rff:1;
+ uint64_t rfne:1;
+ uint64_t tfe:1;
+ uint64_t tfnf:1;
+ uint64_t busy:1;
+ } s;
+ struct cvmx_mio_uartx_usr_s cn30xx;
+ struct cvmx_mio_uartx_usr_s cn31xx;
+ struct cvmx_mio_uartx_usr_s cn38xx;
+ struct cvmx_mio_uartx_usr_s cn38xxp2;
+ struct cvmx_mio_uartx_usr_s cn50xx;
+ struct cvmx_mio_uartx_usr_s cn52xx;
+ struct cvmx_mio_uartx_usr_s cn52xxp1;
+ struct cvmx_mio_uartx_usr_s cn56xx;
+ struct cvmx_mio_uartx_usr_s cn56xxp1;
+ struct cvmx_mio_uartx_usr_s cn58xx;
+ struct cvmx_mio_uartx_usr_s cn58xxp1;
+};
+
+union cvmx_mio_uart2_dlh {
+ uint64_t u64;
+ struct cvmx_mio_uart2_dlh_s {
+ uint64_t reserved_8_63:56;
+ uint64_t dlh:8;
+ } s;
+ struct cvmx_mio_uart2_dlh_s cn52xx;
+ struct cvmx_mio_uart2_dlh_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_dll {
+ uint64_t u64;
+ struct cvmx_mio_uart2_dll_s {
+ uint64_t reserved_8_63:56;
+ uint64_t dll:8;
+ } s;
+ struct cvmx_mio_uart2_dll_s cn52xx;
+ struct cvmx_mio_uart2_dll_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_far {
+ uint64_t u64;
+ struct cvmx_mio_uart2_far_s {
+ uint64_t reserved_1_63:63;
+ uint64_t far:1;
+ } s;
+ struct cvmx_mio_uart2_far_s cn52xx;
+ struct cvmx_mio_uart2_far_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_fcr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_fcr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t rxtrig:2;
+ uint64_t txtrig:2;
+ uint64_t reserved_3_3:1;
+ uint64_t txfr:1;
+ uint64_t rxfr:1;
+ uint64_t en:1;
+ } s;
+ struct cvmx_mio_uart2_fcr_s cn52xx;
+ struct cvmx_mio_uart2_fcr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_htx {
+ uint64_t u64;
+ struct cvmx_mio_uart2_htx_s {
+ uint64_t reserved_1_63:63;
+ uint64_t htx:1;
+ } s;
+ struct cvmx_mio_uart2_htx_s cn52xx;
+ struct cvmx_mio_uart2_htx_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_ier {
+ uint64_t u64;
+ struct cvmx_mio_uart2_ier_s {
+ uint64_t reserved_8_63:56;
+ uint64_t ptime:1;
+ uint64_t reserved_4_6:3;
+ uint64_t edssi:1;
+ uint64_t elsi:1;
+ uint64_t etbei:1;
+ uint64_t erbfi:1;
+ } s;
+ struct cvmx_mio_uart2_ier_s cn52xx;
+ struct cvmx_mio_uart2_ier_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_iir {
+ uint64_t u64;
+ struct cvmx_mio_uart2_iir_s {
+ uint64_t reserved_8_63:56;
+ uint64_t fen:2;
+ uint64_t reserved_4_5:2;
+ uint64_t iid:4;
+ } s;
+ struct cvmx_mio_uart2_iir_s cn52xx;
+ struct cvmx_mio_uart2_iir_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_lcr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_lcr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t dlab:1;
+ uint64_t brk:1;
+ uint64_t reserved_5_5:1;
+ uint64_t eps:1;
+ uint64_t pen:1;
+ uint64_t stop:1;
+ uint64_t cls:2;
+ } s;
+ struct cvmx_mio_uart2_lcr_s cn52xx;
+ struct cvmx_mio_uart2_lcr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_lsr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_lsr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t ferr:1;
+ uint64_t temt:1;
+ uint64_t thre:1;
+ uint64_t bi:1;
+ uint64_t fe:1;
+ uint64_t pe:1;
+ uint64_t oe:1;
+ uint64_t dr:1;
+ } s;
+ struct cvmx_mio_uart2_lsr_s cn52xx;
+ struct cvmx_mio_uart2_lsr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_mcr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_mcr_s {
+ uint64_t reserved_6_63:58;
+ uint64_t afce:1;
+ uint64_t loop:1;
+ uint64_t out2:1;
+ uint64_t out1:1;
+ uint64_t rts:1;
+ uint64_t dtr:1;
+ } s;
+ struct cvmx_mio_uart2_mcr_s cn52xx;
+ struct cvmx_mio_uart2_mcr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_msr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_msr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t dcd:1;
+ uint64_t ri:1;
+ uint64_t dsr:1;
+ uint64_t cts:1;
+ uint64_t ddcd:1;
+ uint64_t teri:1;
+ uint64_t ddsr:1;
+ uint64_t dcts:1;
+ } s;
+ struct cvmx_mio_uart2_msr_s cn52xx;
+ struct cvmx_mio_uart2_msr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_rbr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_rbr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t rbr:8;
+ } s;
+ struct cvmx_mio_uart2_rbr_s cn52xx;
+ struct cvmx_mio_uart2_rbr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_rfl {
+ uint64_t u64;
+ struct cvmx_mio_uart2_rfl_s {
+ uint64_t reserved_7_63:57;
+ uint64_t rfl:7;
+ } s;
+ struct cvmx_mio_uart2_rfl_s cn52xx;
+ struct cvmx_mio_uart2_rfl_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_rfw {
+ uint64_t u64;
+ struct cvmx_mio_uart2_rfw_s {
+ uint64_t reserved_10_63:54;
+ uint64_t rffe:1;
+ uint64_t rfpe:1;
+ uint64_t rfwd:8;
+ } s;
+ struct cvmx_mio_uart2_rfw_s cn52xx;
+ struct cvmx_mio_uart2_rfw_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_sbcr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_sbcr_s {
+ uint64_t reserved_1_63:63;
+ uint64_t sbcr:1;
+ } s;
+ struct cvmx_mio_uart2_sbcr_s cn52xx;
+ struct cvmx_mio_uart2_sbcr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_scr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_scr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t scr:8;
+ } s;
+ struct cvmx_mio_uart2_scr_s cn52xx;
+ struct cvmx_mio_uart2_scr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_sfe {
+ uint64_t u64;
+ struct cvmx_mio_uart2_sfe_s {
+ uint64_t reserved_1_63:63;
+ uint64_t sfe:1;
+ } s;
+ struct cvmx_mio_uart2_sfe_s cn52xx;
+ struct cvmx_mio_uart2_sfe_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_srr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_srr_s {
+ uint64_t reserved_3_63:61;
+ uint64_t stfr:1;
+ uint64_t srfr:1;
+ uint64_t usr:1;
+ } s;
+ struct cvmx_mio_uart2_srr_s cn52xx;
+ struct cvmx_mio_uart2_srr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_srt {
+ uint64_t u64;
+ struct cvmx_mio_uart2_srt_s {
+ uint64_t reserved_2_63:62;
+ uint64_t srt:2;
+ } s;
+ struct cvmx_mio_uart2_srt_s cn52xx;
+ struct cvmx_mio_uart2_srt_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_srts {
+ uint64_t u64;
+ struct cvmx_mio_uart2_srts_s {
+ uint64_t reserved_1_63:63;
+ uint64_t srts:1;
+ } s;
+ struct cvmx_mio_uart2_srts_s cn52xx;
+ struct cvmx_mio_uart2_srts_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_stt {
+ uint64_t u64;
+ struct cvmx_mio_uart2_stt_s {
+ uint64_t reserved_2_63:62;
+ uint64_t stt:2;
+ } s;
+ struct cvmx_mio_uart2_stt_s cn52xx;
+ struct cvmx_mio_uart2_stt_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_tfl {
+ uint64_t u64;
+ struct cvmx_mio_uart2_tfl_s {
+ uint64_t reserved_7_63:57;
+ uint64_t tfl:7;
+ } s;
+ struct cvmx_mio_uart2_tfl_s cn52xx;
+ struct cvmx_mio_uart2_tfl_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_tfr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_tfr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t tfr:8;
+ } s;
+ struct cvmx_mio_uart2_tfr_s cn52xx;
+ struct cvmx_mio_uart2_tfr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_thr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_thr_s {
+ uint64_t reserved_8_63:56;
+ uint64_t thr:8;
+ } s;
+ struct cvmx_mio_uart2_thr_s cn52xx;
+ struct cvmx_mio_uart2_thr_s cn52xxp1;
+};
+
+union cvmx_mio_uart2_usr {
+ uint64_t u64;
+ struct cvmx_mio_uart2_usr_s {
+ uint64_t reserved_5_63:59;
+ uint64_t rff:1;
+ uint64_t rfne:1;
+ uint64_t tfe:1;
+ uint64_t tfnf:1;
+ uint64_t busy:1;
+ } s;
+ struct cvmx_mio_uart2_usr_s cn52xx;
+ struct cvmx_mio_uart2_usr_s cn52xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-packet.h b/arch/mips/include/asm/octeon/cvmx-packet.h
new file mode 100644
index 0000000..38aefa1
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-packet.h
@@ -0,0 +1,61 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * Packet buffer defines.
+ */
+
+#ifndef __CVMX_PACKET_H__
+#define __CVMX_PACKET_H__
+
+/**
+ * This structure defines a buffer pointer on Octeon
+ */
+union cvmx_buf_ptr {
+ void *ptr;
+ uint64_t u64;
+ struct {
+ /* if set, invert the "free" pick of the overall
+ * packet. HW always sets this bit to 0 on inbound
+ * packet */
+ uint64_t i:1;
+
+ /* Indicates the amount to back up to get to the
+ * buffer start in cache lines. In most cases this is
+ * less than one complete cache line, so the value is
+ * zero */
+ uint64_t back:4;
+ /* The pool that the buffer came from / goes to */
+ uint64_t pool:3;
+ /* The size of the segment pointed to by addr (in bytes) */
+ uint64_t size:16;
+ /* Pointer to the first byte of the data, NOT buffer */
+ uint64_t addr:40;
+ } s;
+};
+
+#endif /* __CVMX_PACKET_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-pow-defs.h b/arch/mips/include/asm/octeon/cvmx-pow-defs.h
new file mode 100644
index 0000000..2d82e24
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-pow-defs.h
@@ -0,0 +1,698 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_POW_DEFS_H__
+#define __CVMX_POW_DEFS_H__
+
+#define CVMX_POW_BIST_STAT \
+ CVMX_ADD_IO_SEG(0x00016700000003F8ull)
+#define CVMX_POW_DS_PC \
+ CVMX_ADD_IO_SEG(0x0001670000000398ull)
+#define CVMX_POW_ECC_ERR \
+ CVMX_ADD_IO_SEG(0x0001670000000218ull)
+#define CVMX_POW_INT_CTL \
+ CVMX_ADD_IO_SEG(0x0001670000000220ull)
+#define CVMX_POW_IQ_CNTX(offset) \
+ CVMX_ADD_IO_SEG(0x0001670000000340ull + (((offset) & 7) * 8))
+#define CVMX_POW_IQ_COM_CNT \
+ CVMX_ADD_IO_SEG(0x0001670000000388ull)
+#define CVMX_POW_IQ_INT \
+ CVMX_ADD_IO_SEG(0x0001670000000238ull)
+#define CVMX_POW_IQ_INT_EN \
+ CVMX_ADD_IO_SEG(0x0001670000000240ull)
+#define CVMX_POW_IQ_THRX(offset) \
+ CVMX_ADD_IO_SEG(0x00016700000003A0ull + (((offset) & 7) * 8))
+#define CVMX_POW_NOS_CNT \
+ CVMX_ADD_IO_SEG(0x0001670000000228ull)
+#define CVMX_POW_NW_TIM \
+ CVMX_ADD_IO_SEG(0x0001670000000210ull)
+#define CVMX_POW_PF_RST_MSK \
+ CVMX_ADD_IO_SEG(0x0001670000000230ull)
+#define CVMX_POW_PP_GRP_MSKX(offset) \
+ CVMX_ADD_IO_SEG(0x0001670000000000ull + (((offset) & 15) * 8))
+#define CVMX_POW_QOS_RNDX(offset) \
+ CVMX_ADD_IO_SEG(0x00016700000001C0ull + (((offset) & 7) * 8))
+#define CVMX_POW_QOS_THRX(offset) \
+ CVMX_ADD_IO_SEG(0x0001670000000180ull + (((offset) & 7) * 8))
+#define CVMX_POW_TS_PC \
+ CVMX_ADD_IO_SEG(0x0001670000000390ull)
+#define CVMX_POW_WA_COM_PC \
+ CVMX_ADD_IO_SEG(0x0001670000000380ull)
+#define CVMX_POW_WA_PCX(offset) \
+ CVMX_ADD_IO_SEG(0x0001670000000300ull + (((offset) & 7) * 8))
+#define CVMX_POW_WQ_INT \
+ CVMX_ADD_IO_SEG(0x0001670000000200ull)
+#define CVMX_POW_WQ_INT_CNTX(offset) \
+ CVMX_ADD_IO_SEG(0x0001670000000100ull + (((offset) & 15) * 8))
+#define CVMX_POW_WQ_INT_PC \
+ CVMX_ADD_IO_SEG(0x0001670000000208ull)
+#define CVMX_POW_WQ_INT_THRX(offset) \
+ CVMX_ADD_IO_SEG(0x0001670000000080ull + (((offset) & 15) * 8))
+#define CVMX_POW_WS_PCX(offset) \
+ CVMX_ADD_IO_SEG(0x0001670000000280ull + (((offset) & 15) * 8))
+
+union cvmx_pow_bist_stat {
+ uint64_t u64;
+ struct cvmx_pow_bist_stat_s {
+ uint64_t reserved_32_63:32;
+ uint64_t pp:16;
+ uint64_t reserved_0_15:16;
+ } s;
+ struct cvmx_pow_bist_stat_cn30xx {
+ uint64_t reserved_17_63:47;
+ uint64_t pp:1;
+ uint64_t reserved_9_15:7;
+ uint64_t cam:1;
+ uint64_t nbt1:1;
+ uint64_t nbt0:1;
+ uint64_t index:1;
+ uint64_t fidx:1;
+ uint64_t nbr1:1;
+ uint64_t nbr0:1;
+ uint64_t pend:1;
+ uint64_t adr:1;
+ } cn30xx;
+ struct cvmx_pow_bist_stat_cn31xx {
+ uint64_t reserved_18_63:46;
+ uint64_t pp:2;
+ uint64_t reserved_9_15:7;
+ uint64_t cam:1;
+ uint64_t nbt1:1;
+ uint64_t nbt0:1;
+ uint64_t index:1;
+ uint64_t fidx:1;
+ uint64_t nbr1:1;
+ uint64_t nbr0:1;
+ uint64_t pend:1;
+ uint64_t adr:1;
+ } cn31xx;
+ struct cvmx_pow_bist_stat_cn38xx {
+ uint64_t reserved_32_63:32;
+ uint64_t pp:16;
+ uint64_t reserved_10_15:6;
+ uint64_t cam:1;
+ uint64_t nbt:1;
+ uint64_t index:1;
+ uint64_t fidx:1;
+ uint64_t nbr1:1;
+ uint64_t nbr0:1;
+ uint64_t pend1:1;
+ uint64_t pend0:1;
+ uint64_t adr1:1;
+ uint64_t adr0:1;
+ } cn38xx;
+ struct cvmx_pow_bist_stat_cn38xx cn38xxp2;
+ struct cvmx_pow_bist_stat_cn31xx cn50xx;
+ struct cvmx_pow_bist_stat_cn52xx {
+ uint64_t reserved_20_63:44;
+ uint64_t pp:4;
+ uint64_t reserved_9_15:7;
+ uint64_t cam:1;
+ uint64_t nbt1:1;
+ uint64_t nbt0:1;
+ uint64_t index:1;
+ uint64_t fidx:1;
+ uint64_t nbr1:1;
+ uint64_t nbr0:1;
+ uint64_t pend:1;
+ uint64_t adr:1;
+ } cn52xx;
+ struct cvmx_pow_bist_stat_cn52xx cn52xxp1;
+ struct cvmx_pow_bist_stat_cn56xx {
+ uint64_t reserved_28_63:36;
+ uint64_t pp:12;
+ uint64_t reserved_10_15:6;
+ uint64_t cam:1;
+ uint64_t nbt:1;
+ uint64_t index:1;
+ uint64_t fidx:1;
+ uint64_t nbr1:1;
+ uint64_t nbr0:1;
+ uint64_t pend1:1;
+ uint64_t pend0:1;
+ uint64_t adr1:1;
+ uint64_t adr0:1;
+ } cn56xx;
+ struct cvmx_pow_bist_stat_cn56xx cn56xxp1;
+ struct cvmx_pow_bist_stat_cn38xx cn58xx;
+ struct cvmx_pow_bist_stat_cn38xx cn58xxp1;
+};
+
+union cvmx_pow_ds_pc {
+ uint64_t u64;
+ struct cvmx_pow_ds_pc_s {
+ uint64_t reserved_32_63:32;
+ uint64_t ds_pc:32;
+ } s;
+ struct cvmx_pow_ds_pc_s cn30xx;
+ struct cvmx_pow_ds_pc_s cn31xx;
+ struct cvmx_pow_ds_pc_s cn38xx;
+ struct cvmx_pow_ds_pc_s cn38xxp2;
+ struct cvmx_pow_ds_pc_s cn50xx;
+ struct cvmx_pow_ds_pc_s cn52xx;
+ struct cvmx_pow_ds_pc_s cn52xxp1;
+ struct cvmx_pow_ds_pc_s cn56xx;
+ struct cvmx_pow_ds_pc_s cn56xxp1;
+ struct cvmx_pow_ds_pc_s cn58xx;
+ struct cvmx_pow_ds_pc_s cn58xxp1;
+};
+
+union cvmx_pow_ecc_err {
+ uint64_t u64;
+ struct cvmx_pow_ecc_err_s {
+ uint64_t reserved_45_63:19;
+ uint64_t iop_ie:13;
+ uint64_t reserved_29_31:3;
+ uint64_t iop:13;
+ uint64_t reserved_14_15:2;
+ uint64_t rpe_ie:1;
+ uint64_t rpe:1;
+ uint64_t reserved_9_11:3;
+ uint64_t syn:5;
+ uint64_t dbe_ie:1;
+ uint64_t sbe_ie:1;
+ uint64_t dbe:1;
+ uint64_t sbe:1;
+ } s;
+ struct cvmx_pow_ecc_err_s cn30xx;
+ struct cvmx_pow_ecc_err_cn31xx {
+ uint64_t reserved_14_63:50;
+ uint64_t rpe_ie:1;
+ uint64_t rpe:1;
+ uint64_t reserved_9_11:3;
+ uint64_t syn:5;
+ uint64_t dbe_ie:1;
+ uint64_t sbe_ie:1;
+ uint64_t dbe:1;
+ uint64_t sbe:1;
+ } cn31xx;
+ struct cvmx_pow_ecc_err_s cn38xx;
+ struct cvmx_pow_ecc_err_cn31xx cn38xxp2;
+ struct cvmx_pow_ecc_err_s cn50xx;
+ struct cvmx_pow_ecc_err_s cn52xx;
+ struct cvmx_pow_ecc_err_s cn52xxp1;
+ struct cvmx_pow_ecc_err_s cn56xx;
+ struct cvmx_pow_ecc_err_s cn56xxp1;
+ struct cvmx_pow_ecc_err_s cn58xx;
+ struct cvmx_pow_ecc_err_s cn58xxp1;
+};
+
+union cvmx_pow_int_ctl {
+ uint64_t u64;
+ struct cvmx_pow_int_ctl_s {
+ uint64_t reserved_6_63:58;
+ uint64_t pfr_dis:1;
+ uint64_t nbr_thr:5;
+ } s;
+ struct cvmx_pow_int_ctl_s cn30xx;
+ struct cvmx_pow_int_ctl_s cn31xx;
+ struct cvmx_pow_int_ctl_s cn38xx;
+ struct cvmx_pow_int_ctl_s cn38xxp2;
+ struct cvmx_pow_int_ctl_s cn50xx;
+ struct cvmx_pow_int_ctl_s cn52xx;
+ struct cvmx_pow_int_ctl_s cn52xxp1;
+ struct cvmx_pow_int_ctl_s cn56xx;
+ struct cvmx_pow_int_ctl_s cn56xxp1;
+ struct cvmx_pow_int_ctl_s cn58xx;
+ struct cvmx_pow_int_ctl_s cn58xxp1;
+};
+
+union cvmx_pow_iq_cntx {
+ uint64_t u64;
+ struct cvmx_pow_iq_cntx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t iq_cnt:32;
+ } s;
+ struct cvmx_pow_iq_cntx_s cn30xx;
+ struct cvmx_pow_iq_cntx_s cn31xx;
+ struct cvmx_pow_iq_cntx_s cn38xx;
+ struct cvmx_pow_iq_cntx_s cn38xxp2;
+ struct cvmx_pow_iq_cntx_s cn50xx;
+ struct cvmx_pow_iq_cntx_s cn52xx;
+ struct cvmx_pow_iq_cntx_s cn52xxp1;
+ struct cvmx_pow_iq_cntx_s cn56xx;
+ struct cvmx_pow_iq_cntx_s cn56xxp1;
+ struct cvmx_pow_iq_cntx_s cn58xx;
+ struct cvmx_pow_iq_cntx_s cn58xxp1;
+};
+
+union cvmx_pow_iq_com_cnt {
+ uint64_t u64;
+ struct cvmx_pow_iq_com_cnt_s {
+ uint64_t reserved_32_63:32;
+ uint64_t iq_cnt:32;
+ } s;
+ struct cvmx_pow_iq_com_cnt_s cn30xx;
+ struct cvmx_pow_iq_com_cnt_s cn31xx;
+ struct cvmx_pow_iq_com_cnt_s cn38xx;
+ struct cvmx_pow_iq_com_cnt_s cn38xxp2;
+ struct cvmx_pow_iq_com_cnt_s cn50xx;
+ struct cvmx_pow_iq_com_cnt_s cn52xx;
+ struct cvmx_pow_iq_com_cnt_s cn52xxp1;
+ struct cvmx_pow_iq_com_cnt_s cn56xx;
+ struct cvmx_pow_iq_com_cnt_s cn56xxp1;
+ struct cvmx_pow_iq_com_cnt_s cn58xx;
+ struct cvmx_pow_iq_com_cnt_s cn58xxp1;
+};
+
+union cvmx_pow_iq_int {
+ uint64_t u64;
+ struct cvmx_pow_iq_int_s {
+ uint64_t reserved_8_63:56;
+ uint64_t iq_int:8;
+ } s;
+ struct cvmx_pow_iq_int_s cn52xx;
+ struct cvmx_pow_iq_int_s cn52xxp1;
+ struct cvmx_pow_iq_int_s cn56xx;
+ struct cvmx_pow_iq_int_s cn56xxp1;
+};
+
+union cvmx_pow_iq_int_en {
+ uint64_t u64;
+ struct cvmx_pow_iq_int_en_s {
+ uint64_t reserved_8_63:56;
+ uint64_t int_en:8;
+ } s;
+ struct cvmx_pow_iq_int_en_s cn52xx;
+ struct cvmx_pow_iq_int_en_s cn52xxp1;
+ struct cvmx_pow_iq_int_en_s cn56xx;
+ struct cvmx_pow_iq_int_en_s cn56xxp1;
+};
+
+union cvmx_pow_iq_thrx {
+ uint64_t u64;
+ struct cvmx_pow_iq_thrx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t iq_thr:32;
+ } s;
+ struct cvmx_pow_iq_thrx_s cn52xx;
+ struct cvmx_pow_iq_thrx_s cn52xxp1;
+ struct cvmx_pow_iq_thrx_s cn56xx;
+ struct cvmx_pow_iq_thrx_s cn56xxp1;
+};
+
+union cvmx_pow_nos_cnt {
+ uint64_t u64;
+ struct cvmx_pow_nos_cnt_s {
+ uint64_t reserved_12_63:52;
+ uint64_t nos_cnt:12;
+ } s;
+ struct cvmx_pow_nos_cnt_cn30xx {
+ uint64_t reserved_7_63:57;
+ uint64_t nos_cnt:7;
+ } cn30xx;
+ struct cvmx_pow_nos_cnt_cn31xx {
+ uint64_t reserved_9_63:55;
+ uint64_t nos_cnt:9;
+ } cn31xx;
+ struct cvmx_pow_nos_cnt_s cn38xx;
+ struct cvmx_pow_nos_cnt_s cn38xxp2;
+ struct cvmx_pow_nos_cnt_cn31xx cn50xx;
+ struct cvmx_pow_nos_cnt_cn52xx {
+ uint64_t reserved_10_63:54;
+ uint64_t nos_cnt:10;
+ } cn52xx;
+ struct cvmx_pow_nos_cnt_cn52xx cn52xxp1;
+ struct cvmx_pow_nos_cnt_s cn56xx;
+ struct cvmx_pow_nos_cnt_s cn56xxp1;
+ struct cvmx_pow_nos_cnt_s cn58xx;
+ struct cvmx_pow_nos_cnt_s cn58xxp1;
+};
+
+union cvmx_pow_nw_tim {
+ uint64_t u64;
+ struct cvmx_pow_nw_tim_s {
+ uint64_t reserved_10_63:54;
+ uint64_t nw_tim:10;
+ } s;
+ struct cvmx_pow_nw_tim_s cn30xx;
+ struct cvmx_pow_nw_tim_s cn31xx;
+ struct cvmx_pow_nw_tim_s cn38xx;
+ struct cvmx_pow_nw_tim_s cn38xxp2;
+ struct cvmx_pow_nw_tim_s cn50xx;
+ struct cvmx_pow_nw_tim_s cn52xx;
+ struct cvmx_pow_nw_tim_s cn52xxp1;
+ struct cvmx_pow_nw_tim_s cn56xx;
+ struct cvmx_pow_nw_tim_s cn56xxp1;
+ struct cvmx_pow_nw_tim_s cn58xx;
+ struct cvmx_pow_nw_tim_s cn58xxp1;
+};
+
+union cvmx_pow_pf_rst_msk {
+ uint64_t u64;
+ struct cvmx_pow_pf_rst_msk_s {
+ uint64_t reserved_8_63:56;
+ uint64_t rst_msk:8;
+ } s;
+ struct cvmx_pow_pf_rst_msk_s cn50xx;
+ struct cvmx_pow_pf_rst_msk_s cn52xx;
+ struct cvmx_pow_pf_rst_msk_s cn52xxp1;
+ struct cvmx_pow_pf_rst_msk_s cn56xx;
+ struct cvmx_pow_pf_rst_msk_s cn56xxp1;
+ struct cvmx_pow_pf_rst_msk_s cn58xx;
+ struct cvmx_pow_pf_rst_msk_s cn58xxp1;
+};
+
+union cvmx_pow_pp_grp_mskx {
+ uint64_t u64;
+ struct cvmx_pow_pp_grp_mskx_s {
+ uint64_t reserved_48_63:16;
+ uint64_t qos7_pri:4;
+ uint64_t qos6_pri:4;
+ uint64_t qos5_pri:4;
+ uint64_t qos4_pri:4;
+ uint64_t qos3_pri:4;
+ uint64_t qos2_pri:4;
+ uint64_t qos1_pri:4;
+ uint64_t qos0_pri:4;
+ uint64_t grp_msk:16;
+ } s;
+ struct cvmx_pow_pp_grp_mskx_cn30xx {
+ uint64_t reserved_16_63:48;
+ uint64_t grp_msk:16;
+ } cn30xx;
+ struct cvmx_pow_pp_grp_mskx_cn30xx cn31xx;
+ struct cvmx_pow_pp_grp_mskx_cn30xx cn38xx;
+ struct cvmx_pow_pp_grp_mskx_cn30xx cn38xxp2;
+ struct cvmx_pow_pp_grp_mskx_s cn50xx;
+ struct cvmx_pow_pp_grp_mskx_s cn52xx;
+ struct cvmx_pow_pp_grp_mskx_s cn52xxp1;
+ struct cvmx_pow_pp_grp_mskx_s cn56xx;
+ struct cvmx_pow_pp_grp_mskx_s cn56xxp1;
+ struct cvmx_pow_pp_grp_mskx_s cn58xx;
+ struct cvmx_pow_pp_grp_mskx_s cn58xxp1;
+};
+
+union cvmx_pow_qos_rndx {
+ uint64_t u64;
+ struct cvmx_pow_qos_rndx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t rnd_p3:8;
+ uint64_t rnd_p2:8;
+ uint64_t rnd_p1:8;
+ uint64_t rnd:8;
+ } s;
+ struct cvmx_pow_qos_rndx_s cn30xx;
+ struct cvmx_pow_qos_rndx_s cn31xx;
+ struct cvmx_pow_qos_rndx_s cn38xx;
+ struct cvmx_pow_qos_rndx_s cn38xxp2;
+ struct cvmx_pow_qos_rndx_s cn50xx;
+ struct cvmx_pow_qos_rndx_s cn52xx;
+ struct cvmx_pow_qos_rndx_s cn52xxp1;
+ struct cvmx_pow_qos_rndx_s cn56xx;
+ struct cvmx_pow_qos_rndx_s cn56xxp1;
+ struct cvmx_pow_qos_rndx_s cn58xx;
+ struct cvmx_pow_qos_rndx_s cn58xxp1;
+};
+
+union cvmx_pow_qos_thrx {
+ uint64_t u64;
+ struct cvmx_pow_qos_thrx_s {
+ uint64_t reserved_60_63:4;
+ uint64_t des_cnt:12;
+ uint64_t buf_cnt:12;
+ uint64_t free_cnt:12;
+ uint64_t reserved_23_23:1;
+ uint64_t max_thr:11;
+ uint64_t reserved_11_11:1;
+ uint64_t min_thr:11;
+ } s;
+ struct cvmx_pow_qos_thrx_cn30xx {
+ uint64_t reserved_55_63:9;
+ uint64_t des_cnt:7;
+ uint64_t reserved_43_47:5;
+ uint64_t buf_cnt:7;
+ uint64_t reserved_31_35:5;
+ uint64_t free_cnt:7;
+ uint64_t reserved_18_23:6;
+ uint64_t max_thr:6;
+ uint64_t reserved_6_11:6;
+ uint64_t min_thr:6;
+ } cn30xx;
+ struct cvmx_pow_qos_thrx_cn31xx {
+ uint64_t reserved_57_63:7;
+ uint64_t des_cnt:9;
+ uint64_t reserved_45_47:3;
+ uint64_t buf_cnt:9;
+ uint64_t reserved_33_35:3;
+ uint64_t free_cnt:9;
+ uint64_t reserved_20_23:4;
+ uint64_t max_thr:8;
+ uint64_t reserved_8_11:4;
+ uint64_t min_thr:8;
+ } cn31xx;
+ struct cvmx_pow_qos_thrx_s cn38xx;
+ struct cvmx_pow_qos_thrx_s cn38xxp2;
+ struct cvmx_pow_qos_thrx_cn31xx cn50xx;
+ struct cvmx_pow_qos_thrx_cn52xx {
+ uint64_t reserved_58_63:6;
+ uint64_t des_cnt:10;
+ uint64_t reserved_46_47:2;
+ uint64_t buf_cnt:10;
+ uint64_t reserved_34_35:2;
+ uint64_t free_cnt:10;
+ uint64_t reserved_21_23:3;
+ uint64_t max_thr:9;
+ uint64_t reserved_9_11:3;
+ uint64_t min_thr:9;
+ } cn52xx;
+ struct cvmx_pow_qos_thrx_cn52xx cn52xxp1;
+ struct cvmx_pow_qos_thrx_s cn56xx;
+ struct cvmx_pow_qos_thrx_s cn56xxp1;
+ struct cvmx_pow_qos_thrx_s cn58xx;
+ struct cvmx_pow_qos_thrx_s cn58xxp1;
+};
+
+union cvmx_pow_ts_pc {
+ uint64_t u64;
+ struct cvmx_pow_ts_pc_s {
+ uint64_t reserved_32_63:32;
+ uint64_t ts_pc:32;
+ } s;
+ struct cvmx_pow_ts_pc_s cn30xx;
+ struct cvmx_pow_ts_pc_s cn31xx;
+ struct cvmx_pow_ts_pc_s cn38xx;
+ struct cvmx_pow_ts_pc_s cn38xxp2;
+ struct cvmx_pow_ts_pc_s cn50xx;
+ struct cvmx_pow_ts_pc_s cn52xx;
+ struct cvmx_pow_ts_pc_s cn52xxp1;
+ struct cvmx_pow_ts_pc_s cn56xx;
+ struct cvmx_pow_ts_pc_s cn56xxp1;
+ struct cvmx_pow_ts_pc_s cn58xx;
+ struct cvmx_pow_ts_pc_s cn58xxp1;
+};
+
+union cvmx_pow_wa_com_pc {
+ uint64_t u64;
+ struct cvmx_pow_wa_com_pc_s {
+ uint64_t reserved_32_63:32;
+ uint64_t wa_pc:32;
+ } s;
+ struct cvmx_pow_wa_com_pc_s cn30xx;
+ struct cvmx_pow_wa_com_pc_s cn31xx;
+ struct cvmx_pow_wa_com_pc_s cn38xx;
+ struct cvmx_pow_wa_com_pc_s cn38xxp2;
+ struct cvmx_pow_wa_com_pc_s cn50xx;
+ struct cvmx_pow_wa_com_pc_s cn52xx;
+ struct cvmx_pow_wa_com_pc_s cn52xxp1;
+ struct cvmx_pow_wa_com_pc_s cn56xx;
+ struct cvmx_pow_wa_com_pc_s cn56xxp1;
+ struct cvmx_pow_wa_com_pc_s cn58xx;
+ struct cvmx_pow_wa_com_pc_s cn58xxp1;
+};
+
+union cvmx_pow_wa_pcx {
+ uint64_t u64;
+ struct cvmx_pow_wa_pcx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t wa_pc:32;
+ } s;
+ struct cvmx_pow_wa_pcx_s cn30xx;
+ struct cvmx_pow_wa_pcx_s cn31xx;
+ struct cvmx_pow_wa_pcx_s cn38xx;
+ struct cvmx_pow_wa_pcx_s cn38xxp2;
+ struct cvmx_pow_wa_pcx_s cn50xx;
+ struct cvmx_pow_wa_pcx_s cn52xx;
+ struct cvmx_pow_wa_pcx_s cn52xxp1;
+ struct cvmx_pow_wa_pcx_s cn56xx;
+ struct cvmx_pow_wa_pcx_s cn56xxp1;
+ struct cvmx_pow_wa_pcx_s cn58xx;
+ struct cvmx_pow_wa_pcx_s cn58xxp1;
+};
+
+union cvmx_pow_wq_int {
+ uint64_t u64;
+ struct cvmx_pow_wq_int_s {
+ uint64_t reserved_32_63:32;
+ uint64_t iq_dis:16;
+ uint64_t wq_int:16;
+ } s;
+ struct cvmx_pow_wq_int_s cn30xx;
+ struct cvmx_pow_wq_int_s cn31xx;
+ struct cvmx_pow_wq_int_s cn38xx;
+ struct cvmx_pow_wq_int_s cn38xxp2;
+ struct cvmx_pow_wq_int_s cn50xx;
+ struct cvmx_pow_wq_int_s cn52xx;
+ struct cvmx_pow_wq_int_s cn52xxp1;
+ struct cvmx_pow_wq_int_s cn56xx;
+ struct cvmx_pow_wq_int_s cn56xxp1;
+ struct cvmx_pow_wq_int_s cn58xx;
+ struct cvmx_pow_wq_int_s cn58xxp1;
+};
+
+union cvmx_pow_wq_int_cntx {
+ uint64_t u64;
+ struct cvmx_pow_wq_int_cntx_s {
+ uint64_t reserved_28_63:36;
+ uint64_t tc_cnt:4;
+ uint64_t ds_cnt:12;
+ uint64_t iq_cnt:12;
+ } s;
+ struct cvmx_pow_wq_int_cntx_cn30xx {
+ uint64_t reserved_28_63:36;
+ uint64_t tc_cnt:4;
+ uint64_t reserved_19_23:5;
+ uint64_t ds_cnt:7;
+ uint64_t reserved_7_11:5;
+ uint64_t iq_cnt:7;
+ } cn30xx;
+ struct cvmx_pow_wq_int_cntx_cn31xx {
+ uint64_t reserved_28_63:36;
+ uint64_t tc_cnt:4;
+ uint64_t reserved_21_23:3;
+ uint64_t ds_cnt:9;
+ uint64_t reserved_9_11:3;
+ uint64_t iq_cnt:9;
+ } cn31xx;
+ struct cvmx_pow_wq_int_cntx_s cn38xx;
+ struct cvmx_pow_wq_int_cntx_s cn38xxp2;
+ struct cvmx_pow_wq_int_cntx_cn31xx cn50xx;
+ struct cvmx_pow_wq_int_cntx_cn52xx {
+ uint64_t reserved_28_63:36;
+ uint64_t tc_cnt:4;
+ uint64_t reserved_22_23:2;
+ uint64_t ds_cnt:10;
+ uint64_t reserved_10_11:2;
+ uint64_t iq_cnt:10;
+ } cn52xx;
+ struct cvmx_pow_wq_int_cntx_cn52xx cn52xxp1;
+ struct cvmx_pow_wq_int_cntx_s cn56xx;
+ struct cvmx_pow_wq_int_cntx_s cn56xxp1;
+ struct cvmx_pow_wq_int_cntx_s cn58xx;
+ struct cvmx_pow_wq_int_cntx_s cn58xxp1;
+};
+
+union cvmx_pow_wq_int_pc {
+ uint64_t u64;
+ struct cvmx_pow_wq_int_pc_s {
+ uint64_t reserved_60_63:4;
+ uint64_t pc:28;
+ uint64_t reserved_28_31:4;
+ uint64_t pc_thr:20;
+ uint64_t reserved_0_7:8;
+ } s;
+ struct cvmx_pow_wq_int_pc_s cn30xx;
+ struct cvmx_pow_wq_int_pc_s cn31xx;
+ struct cvmx_pow_wq_int_pc_s cn38xx;
+ struct cvmx_pow_wq_int_pc_s cn38xxp2;
+ struct cvmx_pow_wq_int_pc_s cn50xx;
+ struct cvmx_pow_wq_int_pc_s cn52xx;
+ struct cvmx_pow_wq_int_pc_s cn52xxp1;
+ struct cvmx_pow_wq_int_pc_s cn56xx;
+ struct cvmx_pow_wq_int_pc_s cn56xxp1;
+ struct cvmx_pow_wq_int_pc_s cn58xx;
+ struct cvmx_pow_wq_int_pc_s cn58xxp1;
+};
+
+union cvmx_pow_wq_int_thrx {
+ uint64_t u64;
+ struct cvmx_pow_wq_int_thrx_s {
+ uint64_t reserved_29_63:35;
+ uint64_t tc_en:1;
+ uint64_t tc_thr:4;
+ uint64_t reserved_23_23:1;
+ uint64_t ds_thr:11;
+ uint64_t reserved_11_11:1;
+ uint64_t iq_thr:11;
+ } s;
+ struct cvmx_pow_wq_int_thrx_cn30xx {
+ uint64_t reserved_29_63:35;
+ uint64_t tc_en:1;
+ uint64_t tc_thr:4;
+ uint64_t reserved_18_23:6;
+ uint64_t ds_thr:6;
+ uint64_t reserved_6_11:6;
+ uint64_t iq_thr:6;
+ } cn30xx;
+ struct cvmx_pow_wq_int_thrx_cn31xx {
+ uint64_t reserved_29_63:35;
+ uint64_t tc_en:1;
+ uint64_t tc_thr:4;
+ uint64_t reserved_20_23:4;
+ uint64_t ds_thr:8;
+ uint64_t reserved_8_11:4;
+ uint64_t iq_thr:8;
+ } cn31xx;
+ struct cvmx_pow_wq_int_thrx_s cn38xx;
+ struct cvmx_pow_wq_int_thrx_s cn38xxp2;
+ struct cvmx_pow_wq_int_thrx_cn31xx cn50xx;
+ struct cvmx_pow_wq_int_thrx_cn52xx {
+ uint64_t reserved_29_63:35;
+ uint64_t tc_en:1;
+ uint64_t tc_thr:4;
+ uint64_t reserved_21_23:3;
+ uint64_t ds_thr:9;
+ uint64_t reserved_9_11:3;
+ uint64_t iq_thr:9;
+ } cn52xx;
+ struct cvmx_pow_wq_int_thrx_cn52xx cn52xxp1;
+ struct cvmx_pow_wq_int_thrx_s cn56xx;
+ struct cvmx_pow_wq_int_thrx_s cn56xxp1;
+ struct cvmx_pow_wq_int_thrx_s cn58xx;
+ struct cvmx_pow_wq_int_thrx_s cn58xxp1;
+};
+
+union cvmx_pow_ws_pcx {
+ uint64_t u64;
+ struct cvmx_pow_ws_pcx_s {
+ uint64_t reserved_32_63:32;
+ uint64_t ws_pc:32;
+ } s;
+ struct cvmx_pow_ws_pcx_s cn30xx;
+ struct cvmx_pow_ws_pcx_s cn31xx;
+ struct cvmx_pow_ws_pcx_s cn38xx;
+ struct cvmx_pow_ws_pcx_s cn38xxp2;
+ struct cvmx_pow_ws_pcx_s cn50xx;
+ struct cvmx_pow_ws_pcx_s cn52xx;
+ struct cvmx_pow_ws_pcx_s cn52xxp1;
+ struct cvmx_pow_ws_pcx_s cn56xx;
+ struct cvmx_pow_ws_pcx_s cn56xxp1;
+ struct cvmx_pow_ws_pcx_s cn58xx;
+ struct cvmx_pow_ws_pcx_s cn58xxp1;
+};
+
+#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-spinlock.h b/arch/mips/include/asm/octeon/cvmx-spinlock.h
new file mode 100644
index 0000000..2fbf087
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-spinlock.h
@@ -0,0 +1,232 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/**
+ * Implementation of spinlocks for Octeon CVMX. Although similar in
+ * function to Linux kernel spinlocks, they are not compatible.
+ * Octeon CVMX spinlocks are only used to synchronize with the boot
+ * monitor and other non-Linux programs running in the system.
+ */
+
+#ifndef __CVMX_SPINLOCK_H__
+#define __CVMX_SPINLOCK_H__
+
+#include "cvmx-asm.h"
+
+/* Spinlocks for Octeon */
+
+/* define these to enable recursive spinlock debugging */
+/*#define CVMX_SPINLOCK_DEBUG */
+
+/**
+ * Spinlocks for Octeon CVMX
+ */
+typedef struct {
+ volatile uint32_t value;
+} cvmx_spinlock_t;
+
+/* note - macros not expanded in inline ASM, so values hardcoded */
+#define CVMX_SPINLOCK_UNLOCKED_VAL 0
+#define CVMX_SPINLOCK_LOCKED_VAL 1
+
+#define CVMX_SPINLOCK_UNLOCKED_INITIALIZER {CVMX_SPINLOCK_UNLOCKED_VAL}
+
+/**
+ * Initialize a spinlock
+ *
+ * @lock: Lock to initialize
+ */
+static inline void cvmx_spinlock_init(cvmx_spinlock_t *lock)
+{
+ lock->value = CVMX_SPINLOCK_UNLOCKED_VAL;
+}
+
+/**
+ * Return non-zero if the spinlock is currently locked
+ *
+ * @lock: Lock to check
+ * Returns Non-zero if locked
+ */
+static inline int cvmx_spinlock_locked(cvmx_spinlock_t *lock)
+{
+ return lock->value != CVMX_SPINLOCK_UNLOCKED_VAL;
+}
+
+/**
+ * Releases lock
+ *
+ * @lock: pointer to lock structure
+ */
+static inline void cvmx_spinlock_unlock(cvmx_spinlock_t *lock)
+{
+ CVMX_SYNCWS;
+ lock->value = 0;
+ CVMX_SYNCWS;
+}
+
+/**
+ * Attempts to take the lock, but does not spin if lock is not available.
+ * May take some time to acquire the lock even if it is available
+ * due to the ll/sc not succeeding.
+ *
+ * @lock: pointer to lock structure
+ *
+ * Returns 0: lock successfully taken
+ * 1: lock not taken, held by someone else
+ * These return values match the Linux semantics.
+ */
+
+static inline unsigned int cvmx_spinlock_trylock(cvmx_spinlock_t *lock)
+{
+ unsigned int tmp;
+
+ __asm__ __volatile__(".set noreorder \n"
+ "1: ll %[tmp], %[val] \n"
+ /* if lock held, fail immediately */
+ " bnez %[tmp], 2f \n"
+ " li %[tmp], 1 \n"
+ " sc %[tmp], %[val] \n"
+ " beqz %[tmp], 1b \n"
+ " li %[tmp], 0 \n"
+ "2: \n"
+ ".set reorder \n" :
+ [val] "+m"(lock->value), [tmp] "=&r"(tmp)
+ : : "memory");
+
+ return tmp != 0; /* normalize to 0 or 1 */
+}
+
+/**
+ * Gets lock, spins until lock is taken
+ *
+ * @lock: pointer to lock structure
+ */
+static inline void cvmx_spinlock_lock(cvmx_spinlock_t *lock)
+{
+ unsigned int tmp;
+
+ __asm__ __volatile__(".set noreorder \n"
+ "1: ll %[tmp], %[val] \n"
+ " bnez %[tmp], 1b \n"
+ " li %[tmp], 1 \n"
+ " sc %[tmp], %[val] \n"
+ " beqz %[tmp], 1b \n"
+ " nop \n"
+ ".set reorder \n" :
+ [val] "+m"(lock->value), [tmp] "=&r"(tmp)
+ : : "memory");
+
+}
+
+/** ********************************************************************
+ * Bit spinlocks
+ * These spinlocks use a single bit (bit 31) of a 32 bit word for locking.
+ * The rest of the bits in the word are left undisturbed. This enables more
+ * compact data structures as only 1 bit is consumed for the lock.
+ *
+ */
+
+/**
+ * Gets lock, spins until lock is taken
+ * Preserves the low 31 bits of the 32 bit
+ * word used for the lock.
+ *
+ *
+ * @word: word to lock bit 31 of
+ */
+static inline void cvmx_spinlock_bit_lock(uint32_t *word)
+{
+ unsigned int tmp;
+ unsigned int sav;
+
+ __asm__ __volatile__(".set noreorder \n"
+ ".set noat \n"
+ "1: ll %[tmp], %[val] \n"
+ " bbit1 %[tmp], 31, 1b \n"
+ " li $at, 1 \n"
+ " ins %[tmp], $at, 31, 1 \n"
+ " sc %[tmp], %[val] \n"
+ " beqz %[tmp], 1b \n"
+ " nop \n"
+ ".set at \n"
+ ".set reorder \n" :
+ [val] "+m"(*word), [tmp] "=&r"(tmp), [sav] "=&r"(sav)
+ : : "memory");
+
+}
+
+/**
+ * Attempts to get lock, returns immediately with success/failure
+ * Preserves the low 31 bits of the 32 bit
+ * word used for the lock.
+ *
+ *
+ * @word: word to lock bit 31 of
+ * Returns 0: lock successfully taken
+ * 1: lock not taken, held by someone else
+ * These return values match the Linux semantics.
+ */
+static inline unsigned int cvmx_spinlock_bit_trylock(uint32_t *word)
+{
+ unsigned int tmp;
+
+ __asm__ __volatile__(".set noreorder\n\t"
+ ".set noat\n"
+ "1: ll %[tmp], %[val] \n"
+ /* if lock held, fail immediately */
+ " bbit1 %[tmp], 31, 2f \n"
+ " li $at, 1 \n"
+ " ins %[tmp], $at, 31, 1 \n"
+ " sc %[tmp], %[val] \n"
+ " beqz %[tmp], 1b \n"
+ " li %[tmp], 0 \n"
+ "2: \n"
+ ".set at \n"
+ ".set reorder \n" :
+ [val] "+m"(*word), [tmp] "=&r"(tmp)
+ : : "memory");
+
+ return tmp != 0; /* normalize to 0 or 1 */
+}
+
+/**
+ * Releases bit lock
+ *
+ * Unconditionally clears bit 31 of the lock word. Note that this is
+ * done non-atomically, as this implementation assumes that the rest
+ * of the bits in the word are protected by the lock.
+ *
+ * @word: word to unlock bit 31 in
+ */
+static inline void cvmx_spinlock_bit_unlock(uint32_t *word)
+{
+ CVMX_SYNCWS;
+ *word &= ~(1UL << 31);
+ CVMX_SYNCWS;
+}
+
+#endif /* __CVMX_SPINLOCK_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-sysinfo.h b/arch/mips/include/asm/octeon/cvmx-sysinfo.h
new file mode 100644
index 0000000..61dd574
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx-sysinfo.h
@@ -0,0 +1,152 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * This module provides system/board information obtained by the bootloader.
+ */
+
+#ifndef __CVMX_SYSINFO_H__
+#define __CVMX_SYSINFO_H__
+
+#define OCTEON_SERIAL_LEN 20
+/**
+ * Structure describing application specific information.
+ * __cvmx_app_init() populates this from the cvmx boot descriptor.
+ * This structure is private to simple executive applications, so
+ * no versioning is required.
+ *
+ * This structure must be provided with some fields set in order to
+ * use simple executive functions in other applications (Linux kernel,
+ * u-boot, etc.) The cvmx_sysinfo_minimal_initialize() function is
+ * provided to set the required values in these cases.
+ */
+struct cvmx_sysinfo {
+ /* System wide variables */
+ /* installed DRAM in system, in bytes */
+ uint64_t system_dram_size;
+
+ /* ptr to memory descriptor block */
+ void *phy_mem_desc_ptr;
+
+
+ /* Application image specific variables */
+ /* stack top address (virtual) */
+ uint64_t stack_top;
+ /* heap base address (virtual) */
+ uint64_t heap_base;
+ /* stack size in bytes */
+ uint32_t stack_size;
+ /* heap size in bytes */
+ uint32_t heap_size;
+ /* coremask defining cores running application */
+ uint32_t core_mask;
+ /* Deprecated, use cvmx_coremask_first_core() to select init core */
+ uint32_t init_core;
+
+ /* exception base address, as set by bootloader */
+ uint64_t exception_base_addr;
+
+ /* cpu clock speed in hz */
+ uint32_t cpu_clock_hz;
+
+ /* dram data rate in hz (data rate = 2 * clock rate */
+ uint32_t dram_data_rate_hz;
+
+
+ uint16_t board_type;
+ uint8_t board_rev_major;
+ uint8_t board_rev_minor;
+ uint8_t mac_addr_base[6];
+ uint8_t mac_addr_count;
+ char board_serial_number[OCTEON_SERIAL_LEN];
+ /*
+ * Several boards support compact flash on the Octeon boot
+ * bus. The CF memory spaces may be mapped to different
+ * addresses on different boards. These values will be 0 if
+ * CF is not present. Note that these addresses are physical
+ * addresses, and it is up to the application to use the
+ * proper addressing mode (XKPHYS, KSEG0, etc.)
+ */
+ uint64_t compact_flash_common_base_addr;
+ uint64_t compact_flash_attribute_base_addr;
+ /*
+ * Base address of the LED display (as on EBT3000 board) This
+ * will be 0 if LED display not present. Note that this
+ * address is a physical address, and it is up to the
+ * application to use the proper addressing mode (XKPHYS,
+ * KSEG0, etc.)
+ */
+ uint64_t led_display_base_addr;
+ /* DFA reference clock in hz (if applicable)*/
+ uint32_t dfa_ref_clock_hz;
+ /* configuration flags from bootloader */
+ uint32_t bootloader_config_flags;
+
+ /* Uart number used for console */
+ uint8_t console_uart_num;
+};
+
+/**
+ * This function returns the system/board information as obtained
+ * by the bootloader.
+ *
+ *
+ * Returns Pointer to the boot information structure
+ *
+ */
+
+extern struct cvmx_sysinfo *cvmx_sysinfo_get(void);
+
+/**
+ * This function is used in non-simple executive environments (such as
+ * Linux kernel, u-boot, etc.) to configure the minimal fields that
+ * are required to use simple executive files directly.
+ *
+ * Locking (if required) must be handled outside of this
+ * function
+ *
+ * @phy_mem_desc_ptr: Pointer to global physical memory descriptor
+ * (bootmem descriptor) @board_type: Octeon board
+ * type enumeration
+ *
+ * @board_rev_major:
+ * Board major revision
+ * @board_rev_minor:
+ * Board minor revision
+ * @cpu_clock_hz:
+ * CPU clock freqency in hertz
+ *
+ * Returns 0: Failure
+ * 1: success
+ */
+extern int cvmx_sysinfo_minimal_initialize(void *phy_mem_desc_ptr,
+ uint16_t board_type,
+ uint8_t board_rev_major,
+ uint8_t board_rev_minor,
+ uint32_t cpu_clock_hz);
+
+#endif /* __CVMX_SYSINFO_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx.h b/arch/mips/include/asm/octeon/cvmx.h
new file mode 100644
index 0000000..03fddfa
--- /dev/null
+++ b/arch/mips/include/asm/octeon/cvmx.h
@@ -0,0 +1,505 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+#ifndef __CVMX_H__
+#define __CVMX_H__
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+
+#include "cvmx-asm.h"
+#include "cvmx-packet.h"
+#include "cvmx-sysinfo.h"
+
+#include "cvmx-ciu-defs.h"
+#include "cvmx-gpio-defs.h"
+#include "cvmx-iob-defs.h"
+#include "cvmx-ipd-defs.h"
+#include "cvmx-l2c-defs.h"
+#include "cvmx-l2d-defs.h"
+#include "cvmx-l2t-defs.h"
+#include "cvmx-led-defs.h"
+#include "cvmx-mio-defs.h"
+#include "cvmx-pow-defs.h"
+
+#include "cvmx-bootinfo.h"
+#include "cvmx-bootmem.h"
+#include "cvmx-l2c.h"
+
+#ifndef CVMX_ENABLE_DEBUG_PRINTS
+#define CVMX_ENABLE_DEBUG_PRINTS 1
+#endif
+
+#if CVMX_ENABLE_DEBUG_PRINTS
+#define cvmx_dprintf printk
+#else
+#define cvmx_dprintf(...) {}
+#endif
+
+#define CVMX_MAX_CORES (16)
+#define CVMX_CACHE_LINE_SIZE (128) /* In bytes */
+#define CVMX_CACHE_LINE_MASK (CVMX_CACHE_LINE_SIZE - 1) /* In bytes */
+#define CVMX_CACHE_LINE_ALIGNED __attribute__ ((aligned(CVMX_CACHE_LINE_SIZE)))
+#define CAST64(v) ((long long)(long)(v))
+#define CASTPTR(type, v) ((type *)(long)(v))
+
+/*
+ * Returns processor ID, different Linux and simple exec versions
+ * provided in the cvmx-app-init*.c files.
+ */
+static inline uint32_t cvmx_get_proc_id(void) __attribute__ ((pure));
+static inline uint32_t cvmx_get_proc_id(void)
+{
+ uint32_t id;
+ asm("mfc0 %0, $15,0" : "=r"(id));
+ return id;
+}
+
+/* turn the variable name into a string */
+#define CVMX_TMP_STR(x) CVMX_TMP_STR2(x)
+#define CVMX_TMP_STR2(x) #x
+
+/**
+ * Builds a bit mask given the required size in bits.
+ *
+ * @bits: Number of bits in the mask
+ * Returns The mask
+ */ static inline uint64_t cvmx_build_mask(uint64_t bits)
+{
+ return ~((~0x0ull) << bits);
+}
+
+/**
+ * Builds a memory address for I/O based on the Major and Sub DID.
+ *
+ * @major_did: 5 bit major did
+ * @sub_did: 3 bit sub did
+ * Returns I/O base address
+ */
+static inline uint64_t cvmx_build_io_address(uint64_t major_did,
+ uint64_t sub_did)
+{
+ return (0x1ull << 48) | (major_did << 43) | (sub_did << 40);
+}
+
+/**
+ * Perform mask and shift to place the supplied value into
+ * the supplied bit rage.
+ *
+ * Example: cvmx_build_bits(39,24,value)
+ * <pre>
+ * 6 5 4 3 3 2 1
+ * 3 5 7 9 1 3 5 7 0
+ * +-------+-------+-------+-------+-------+-------+-------+------+
+ * 000000000000000000000000___________value000000000000000000000000
+ * </pre>
+ *
+ * @high_bit: Highest bit value can occupy (inclusive) 0-63
+ * @low_bit: Lowest bit value can occupy inclusive 0-high_bit
+ * @value: Value to use
+ * Returns Value masked and shifted
+ */
+static inline uint64_t cvmx_build_bits(uint64_t high_bit,
+ uint64_t low_bit, uint64_t value)
+{
+ return (value & cvmx_build_mask(high_bit - low_bit + 1)) << low_bit;
+}
+
+enum cvmx_mips_space {
+ CVMX_MIPS_SPACE_XKSEG = 3LL,
+ CVMX_MIPS_SPACE_XKPHYS = 2LL,
+ CVMX_MIPS_SPACE_XSSEG = 1LL,
+ CVMX_MIPS_SPACE_XUSEG = 0LL
+};
+
+/* These macros for use when using 32 bit pointers. */
+#define CVMX_MIPS32_SPACE_KSEG0 1l
+#define CVMX_ADD_SEG32(segment, add) \
+ (((int32_t)segment << 31) | (int32_t)(add))
+
+#define CVMX_IO_SEG CVMX_MIPS_SPACE_XKPHYS
+
+/* These macros simplify the process of creating common IO addresses */
+#define CVMX_ADD_SEG(segment, add) \
+ ((((uint64_t)segment) << 62) | (add))
+#ifndef CVMX_ADD_IO_SEG
+#define CVMX_ADD_IO_SEG(add) CVMX_ADD_SEG(CVMX_IO_SEG, (add))
+#endif
+
+/**
+ * Convert a memory pointer (void*) into a hardware compatable
+ * memory address (uint64_t). Octeon hardware widgets don't
+ * understand logical addresses.
+ *
+ * @ptr: C style memory pointer
+ * Returns Hardware physical address
+ */
+static inline uint64_t cvmx_ptr_to_phys(void *ptr)
+{
+ if (sizeof(void *) == 8) {
+ /*
+ * We're running in 64 bit mode. Normally this means
+ * that we can use 40 bits of address space (the
+ * hardware limit). Unfortunately there is one case
+ * were we need to limit this to 30 bits, sign
+ * extended 32 bit. Although these are 64 bits wide,
+ * only 30 bits can be used.
+ */
+ if ((CAST64(ptr) >> 62) == 3)
+ return CAST64(ptr) & cvmx_build_mask(30);
+ else
+ return CAST64(ptr) & cvmx_build_mask(40);
+ } else {
+ return (long)(ptr) & 0x1fffffff;
+ }
+}
+
+/**
+ * Convert a hardware physical address (uint64_t) into a
+ * memory pointer (void *).
+ *
+ * @physical_address:
+ * Hardware physical address to memory
+ * Returns Pointer to memory
+ */
+static inline void *cvmx_phys_to_ptr(uint64_t physical_address)
+{
+ if (sizeof(void *) == 8) {
+ /* Just set the top bit, avoiding any TLB uglyness */
+ return CASTPTR(void,
+ CVMX_ADD_SEG(CVMX_MIPS_SPACE_XKPHYS,
+ physical_address));
+ } else {
+ return CASTPTR(void,
+ CVMX_ADD_SEG32(CVMX_MIPS32_SPACE_KSEG0,
+ physical_address));
+ }
+}
+
+/* The following #if controls the definition of the macro
+ CVMX_BUILD_WRITE64. This macro is used to build a store operation to
+ a full 64bit address. With a 64bit ABI, this can be done with a simple
+ pointer access. 32bit ABIs require more complicated assembly */
+
+/* We have a full 64bit ABI. Writing to a 64bit address can be done with
+ a simple volatile pointer */
+#define CVMX_BUILD_WRITE64(TYPE, ST) \
+static inline void cvmx_write64_##TYPE(uint64_t addr, TYPE##_t val) \
+{ \
+ *CASTPTR(volatile TYPE##_t, addr) = val; \
+}
+
+
+/* The following #if controls the definition of the macro
+ CVMX_BUILD_READ64. This macro is used to build a load operation from
+ a full 64bit address. With a 64bit ABI, this can be done with a simple
+ pointer access. 32bit ABIs require more complicated assembly */
+
+/* We have a full 64bit ABI. Writing to a 64bit address can be done with
+ a simple volatile pointer */
+#define CVMX_BUILD_READ64(TYPE, LT) \
+static inline TYPE##_t cvmx_read64_##TYPE(uint64_t addr) \
+{ \
+ return *CASTPTR(volatile TYPE##_t, addr); \
+}
+
+
+/* The following defines 8 functions for writing to a 64bit address. Each
+ takes two arguments, the address and the value to write.
+ cvmx_write64_int64 cvmx_write64_uint64
+ cvmx_write64_int32 cvmx_write64_uint32
+ cvmx_write64_int16 cvmx_write64_uint16
+ cvmx_write64_int8 cvmx_write64_uint8 */
+CVMX_BUILD_WRITE64(int64, "sd");
+CVMX_BUILD_WRITE64(int32, "sw");
+CVMX_BUILD_WRITE64(int16, "sh");
+CVMX_BUILD_WRITE64(int8, "sb");
+CVMX_BUILD_WRITE64(uint64, "sd");
+CVMX_BUILD_WRITE64(uint32, "sw");
+CVMX_BUILD_WRITE64(uint16, "sh");
+CVMX_BUILD_WRITE64(uint8, "sb");
+#define cvmx_write64 cvmx_write64_uint64
+
+/* The following defines 8 functions for reading from a 64bit address. Each
+ takes the address as the only argument
+ cvmx_read64_int64 cvmx_read64_uint64
+ cvmx_read64_int32 cvmx_read64_uint32
+ cvmx_read64_int16 cvmx_read64_uint16
+ cvmx_read64_int8 cvmx_read64_uint8 */
+CVMX_BUILD_READ64(int64, "ld");
+CVMX_BUILD_READ64(int32, "lw");
+CVMX_BUILD_READ64(int16, "lh");
+CVMX_BUILD_READ64(int8, "lb");
+CVMX_BUILD_READ64(uint64, "ld");
+CVMX_BUILD_READ64(uint32, "lw");
+CVMX_BUILD_READ64(uint16, "lhu");
+CVMX_BUILD_READ64(uint8, "lbu");
+#define cvmx_read64 cvmx_read64_uint64
+
+
+static inline void cvmx_write_csr(uint64_t csr_addr, uint64_t val)
+{
+ cvmx_write64(csr_addr, val);
+
+ /*
+ * Perform an immediate read after every write to an RSL
+ * register to force the write to complete. It doesn't matter
+ * what RSL read we do, so we choose CVMX_MIO_BOOT_BIST_STAT
+ * because it is fast and harmless.
+ */
+ if ((csr_addr >> 40) == (0x800118))
+ cvmx_read64(CVMX_MIO_BOOT_BIST_STAT);
+}
+
+static inline void cvmx_write_io(uint64_t io_addr, uint64_t val)
+{
+ cvmx_write64(io_addr, val);
+
+}
+
+static inline uint64_t cvmx_read_csr(uint64_t csr_addr)
+{
+ uint64_t val = cvmx_read64(csr_addr);
+ return val;
+}
+
+
+static inline void cvmx_send_single(uint64_t data)
+{
+ const uint64_t CVMX_IOBDMA_SENDSINGLE = 0xffffffffffffa200ull;
+ cvmx_write64(CVMX_IOBDMA_SENDSINGLE, data);
+}
+
+static inline void cvmx_read_csr_async(uint64_t scraddr, uint64_t csr_addr)
+{
+ union {
+ uint64_t u64;
+ struct {
+ uint64_t scraddr:8;
+ uint64_t len:8;
+ uint64_t addr:48;
+ } s;
+ } addr;
+ addr.u64 = csr_addr;
+ addr.s.scraddr = scraddr >> 3;
+ addr.s.len = 1;
+ cvmx_send_single(addr.u64);
+}
+
+/* Return true if Octeon is CN38XX pass 1 */
+static inline int cvmx_octeon_is_pass1(void)
+{
+#if OCTEON_IS_COMMON_BINARY()
+ return 0; /* Pass 1 isn't supported for common binaries */
+#else
+/* Now that we know we're built for a specific model, only check CN38XX */
+#if OCTEON_IS_MODEL(OCTEON_CN38XX)
+ return cvmx_get_proc_id() == OCTEON_CN38XX_PASS1;
+#else
+ return 0; /* Built for non CN38XX chip, we're not CN38XX pass1 */
+#endif
+#endif
+}
+
+static inline unsigned int cvmx_get_core_num(void)
+{
+ unsigned int core_num;
+ CVMX_RDHWRNV(core_num, 0);
+ return core_num;
+}
+
+/**
+ * Returns the number of bits set in the provided value.
+ * Simple wrapper for POP instruction.
+ *
+ * @val: 32 bit value to count set bits in
+ *
+ * Returns Number of bits set
+ */
+static inline uint32_t cvmx_pop(uint32_t val)
+{
+ uint32_t pop;
+ CVMX_POP(pop, val);
+ return pop;
+}
+
+/**
+ * Returns the number of bits set in the provided value.
+ * Simple wrapper for DPOP instruction.
+ *
+ * @val: 64 bit value to count set bits in
+ *
+ * Returns Number of bits set
+ */
+static inline int cvmx_dpop(uint64_t val)
+{
+ int pop;
+ CVMX_DPOP(pop, val);
+ return pop;
+}
+
+/**
+ * Provide current cycle counter as a return value
+ *
+ * Returns current cycle counter
+ */
+
+static inline uint64_t cvmx_get_cycle(void)
+{
+ uint64_t cycle;
+ CVMX_RDHWR(cycle, 31);
+ return cycle;
+}
+
+/**
+ * Reads a chip global cycle counter. This counts CPU cycles since
+ * chip reset. The counter is 64 bit.
+ * This register does not exist on CN38XX pass 1 silicion
+ *
+ * Returns Global chip cycle count since chip reset.
+ */
+static inline uint64_t cvmx_get_cycle_global(void)
+{
+ if (cvmx_octeon_is_pass1())
+ return 0;
+ else
+ return cvmx_read64(CVMX_IPD_CLK_COUNT);
+}
+
+/**
+ * This macro spins on a field waiting for it to reach a value. It
+ * is common in code to need to wait for a specific field in a CSR
+ * to match a specific value. Conceptually this macro expands to:
+ *
+ * 1) read csr at "address" with a csr typedef of "type"
+ * 2) Check if ("type".s."field" "op" "value")
+ * 3) If #2 isn't true loop to #1 unless too much time has passed.
+ */
+#define CVMX_WAIT_FOR_FIELD64(address, type, field, op, value, timeout_usec)\
+ ( \
+{ \
+ int result; \
+ do { \
+ uint64_t done = cvmx_get_cycle() + (uint64_t)timeout_usec * \
+ cvmx_sysinfo_get()->cpu_clock_hz / 1000000; \
+ type c; \
+ while (1) { \
+ c.u64 = cvmx_read_csr(address); \
+ if ((c.s.field) op(value)) { \
+ result = 0; \
+ break; \
+ } else if (cvmx_get_cycle() > done) { \
+ result = -1; \
+ break; \
+ } else \
+ cvmx_wait(100); \
+ } \
+ } while (0); \
+ result; \
+})
+
+/***************************************************************************/
+
+static inline void cvmx_reset_octeon(void)
+{
+ union cvmx_ciu_soft_rst ciu_soft_rst;
+ ciu_soft_rst.u64 = 0;
+ ciu_soft_rst.s.soft_rst = 1;
+ cvmx_write_csr(CVMX_CIU_SOFT_RST, ciu_soft_rst.u64);
+}
+
+/* Return the number of cores available in the chip */
+static inline uint32_t cvmx_octeon_num_cores(void)
+{
+ uint32_t ciu_fuse = (uint32_t) cvmx_read_csr(CVMX_CIU_FUSE) & 0xffff;
+ return cvmx_pop(ciu_fuse);
+}
+
+/**
+ * Read a byte of fuse data
+ * @byte_addr: address to read
+ *
+ * Returns fuse value: 0 or 1
+ */
+static uint8_t cvmx_fuse_read_byte(int byte_addr)
+{
+ union cvmx_mio_fus_rcmd read_cmd;
+
+ read_cmd.u64 = 0;
+ read_cmd.s.addr = byte_addr;
+ read_cmd.s.pend = 1;
+ cvmx_write_csr(CVMX_MIO_FUS_RCMD, read_cmd.u64);
+ while ((read_cmd.u64 = cvmx_read_csr(CVMX_MIO_FUS_RCMD))
+ && read_cmd.s.pend)
+ ;
+ return read_cmd.s.dat;
+}
+
+/**
+ * Read a single fuse bit
+ *
+ * @fuse: Fuse number (0-1024)
+ *
+ * Returns fuse value: 0 or 1
+ */
+static inline int cvmx_fuse_read(int fuse)
+{
+ return (cvmx_fuse_read_byte(fuse >> 3) >> (fuse & 0x7)) & 1;
+}
+
+static inline int cvmx_octeon_model_CN36XX(void)
+{
+ return OCTEON_IS_MODEL(OCTEON_CN38XX)
+ && !cvmx_octeon_is_pass1()
+ && cvmx_fuse_read(264);
+}
+
+static inline int cvmx_octeon_zip_present(void)
+{
+ return octeon_has_feature(OCTEON_FEATURE_ZIP);
+}
+
+static inline int cvmx_octeon_dfa_present(void)
+{
+ if (!OCTEON_IS_MODEL(OCTEON_CN38XX)
+ && !OCTEON_IS_MODEL(OCTEON_CN31XX)
+ && !OCTEON_IS_MODEL(OCTEON_CN58XX))
+ return 0;
+ else if (OCTEON_IS_MODEL(OCTEON_CN3020))
+ return 0;
+ else if (cvmx_octeon_is_pass1())
+ return 1;
+ else
+ return !cvmx_fuse_read(120);
+}
+
+static inline int cvmx_octeon_crypto_present(void)
+{
+ return octeon_has_feature(OCTEON_FEATURE_CRYPTO);
+}
+
+#endif /* __CVMX_H__ */
diff --git a/arch/mips/include/asm/octeon/octeon-feature.h b/arch/mips/include/asm/octeon/octeon-feature.h
new file mode 100644
index 0000000..04fac68
--- /dev/null
+++ b/arch/mips/include/asm/octeon/octeon-feature.h
@@ -0,0 +1,119 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ * File defining checks for different Octeon features.
+ */
+
+#ifndef __OCTEON_FEATURE_H__
+#define __OCTEON_FEATURE_H__
+
+enum octeon_feature {
+ /*
+ * Octeon models in the CN5XXX family and higher support
+ * atomic add instructions to memory (saa/saad).
+ */
+ OCTEON_FEATURE_SAAD,
+ /* Does this Octeon support the ZIP offload engine? */
+ OCTEON_FEATURE_ZIP,
+ /* Does this Octeon support crypto acceleration using COP2? */
+ OCTEON_FEATURE_CRYPTO,
+ /* Does this Octeon support PCI express? */
+ OCTEON_FEATURE_PCIE,
+ /* Some Octeon models support internal memory for storing
+ * cryptographic keys */
+ OCTEON_FEATURE_KEY_MEMORY,
+ /* Octeon has a LED controller for banks of external LEDs */
+ OCTEON_FEATURE_LED_CONTROLLER,
+ /* Octeon has a trace buffer */
+ OCTEON_FEATURE_TRA,
+ /* Octeon has a management port */
+ OCTEON_FEATURE_MGMT_PORT,
+ /* Octeon has a raid unit */
+ OCTEON_FEATURE_RAID,
+ /* Octeon has a builtin USB */
+ OCTEON_FEATURE_USB,
+};
+
+static inline int cvmx_fuse_read(int fuse);
+
+/**
+ * Determine if the current Octeon supports a specific feature. These
+ * checks have been optimized to be fairly quick, but they should still
+ * be kept out of fast path code.
+ *
+ * @feature: Feature to check for. This should always be a constant so the
+ * compiler can remove the switch statement through optimization.
+ *
+ * Returns Non zero if the feature exists. Zero if the feature does not
+ * exist.
+ */
+static inline int octeon_has_feature(enum octeon_feature feature)
+{
+ switch (feature) {
+ case OCTEON_FEATURE_SAAD:
+ return !OCTEON_IS_MODEL(OCTEON_CN3XXX);
+
+ case OCTEON_FEATURE_ZIP:
+ if (OCTEON_IS_MODEL(OCTEON_CN30XX)
+ || OCTEON_IS_MODEL(OCTEON_CN50XX)
+ || OCTEON_IS_MODEL(OCTEON_CN52XX))
+ return 0;
+ else if (OCTEON_IS_MODEL(OCTEON_CN38XX_PASS1))
+ return 1;
+ else
+ return !cvmx_fuse_read(121);
+
+ case OCTEON_FEATURE_CRYPTO:
+ return !cvmx_fuse_read(90);
+
+ case OCTEON_FEATURE_PCIE:
+ return OCTEON_IS_MODEL(OCTEON_CN56XX)
+ || OCTEON_IS_MODEL(OCTEON_CN52XX);
+
+ case OCTEON_FEATURE_KEY_MEMORY:
+ case OCTEON_FEATURE_LED_CONTROLLER:
+ return OCTEON_IS_MODEL(OCTEON_CN38XX)
+ || OCTEON_IS_MODEL(OCTEON_CN58XX)
+ || OCTEON_IS_MODEL(OCTEON_CN56XX);
+ case OCTEON_FEATURE_TRA:
+ return !(OCTEON_IS_MODEL(OCTEON_CN30XX)
+ || OCTEON_IS_MODEL(OCTEON_CN50XX));
+ case OCTEON_FEATURE_MGMT_PORT:
+ return OCTEON_IS_MODEL(OCTEON_CN56XX)
+ || OCTEON_IS_MODEL(OCTEON_CN52XX);
+ case OCTEON_FEATURE_RAID:
+ return OCTEON_IS_MODEL(OCTEON_CN56XX)
+ || OCTEON_IS_MODEL(OCTEON_CN52XX);
+ case OCTEON_FEATURE_USB:
+ return !(OCTEON_IS_MODEL(OCTEON_CN38XX)
+ || OCTEON_IS_MODEL(OCTEON_CN58XX));
+ }
+ return 0;
+}
+
+#endif /* __OCTEON_FEATURE_H__ */
diff --git a/arch/mips/include/asm/octeon/octeon-model.h b/arch/mips/include/asm/octeon/octeon-model.h
new file mode 100644
index 0000000..cf50336
--- /dev/null
+++ b/arch/mips/include/asm/octeon/octeon-model.h
@@ -0,0 +1,321 @@
+/***********************license start***************
+ * Author: Cavium Networks
+ *
+ * Contact: support@caviumnetworks.com
+ * This file is part of the OCTEON SDK
+ *
+ * Copyright (c) 2003-2008 Cavium Networks
+ *
+ * This file is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License, Version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * AS-IS and WITHOUT ANY WARRANTY; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, TITLE, or
+ * NONINFRINGEMENT. See the GNU General Public License for more
+ * details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this file; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ * or visit http://www.gnu.org/licenses/.
+ *
+ * This file may also be available under a different license from Cavium.
+ * Contact Cavium Networks for more information
+ ***********************license end**************************************/
+
+/*
+ *
+ * File defining different Octeon model IDs and macros to
+ * compare them.
+ *
+ */
+
+#ifndef __OCTEON_MODEL_H__
+#define __OCTEON_MODEL_H__
+
+/* NOTE: These must match what is checked in common-config.mk */
+/* Defines to represent the different versions of Octeon. */
+
+/*
+ * IMPORTANT: When the default pass is updated for an Octeon Model,
+ * the corresponding change must also be made in the oct-sim script.
+ */
+
+/*
+ * The defines below should be used with the OCTEON_IS_MODEL() macro
+ * to determine what model of chip the software is running on. Models
+ * ending in 'XX' match multiple models (families), while specific
+ * models match only that model. If a pass (revision) is specified,
+ * then only that revision will be matched. Care should be taken when
+ * checking for both specific models and families that the specific
+ * models are checked for first. While these defines are similar to
+ * the processor ID, they are not intended to be used by anything
+ * other that the OCTEON_IS_MODEL framework, and the values are
+ * subject to change at anytime without notice.
+ *
+ * NOTE: only the OCTEON_IS_MODEL() macro/function and the OCTEON_CN*
+ * macros should be used outside of this file. All other macros are
+ * for internal use only, and may change without notice.
+ */
+
+/* Flag bits in top byte */
+/* Ignores revision in model checks */
+#define OM_IGNORE_REVISION 0x01000000
+/* Check submodels */
+#define OM_CHECK_SUBMODEL 0x02000000
+/* Match all models previous than the one specified */
+#define OM_MATCH_PREVIOUS_MODELS 0x04000000
+/* Ignores the minor revison on newer parts */
+#define OM_IGNORE_MINOR_REVISION 0x08000000
+#define OM_FLAG_MASK 0xff000000
+
+/*
+ * CN5XXX models with new revision encoding
+ */
+#define OCTEON_CN58XX_PASS1_0 0x000d0300
+#define OCTEON_CN58XX_PASS1_1 0x000d0301
+#define OCTEON_CN58XX_PASS1_2 0x000d0303
+#define OCTEON_CN58XX_PASS2_0 0x000d0308
+#define OCTEON_CN58XX_PASS2_1 0x000d0309
+#define OCTEON_CN58XX_PASS2_2 0x000d030a
+#define OCTEON_CN58XX_PASS2_3 0x000d030b
+
+#define OCTEON_CN58XX (OCTEON_CN58XX_PASS1_0 | OM_IGNORE_REVISION)
+#define OCTEON_CN58XX_PASS1_X (OCTEON_CN58XX_PASS1_0 \
+ | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN58XX_PASS2_X (OCTEON_CN58XX_PASS2_0 \
+ | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN58XX_PASS1 OCTEON_CN58XX_PASS1_X
+#define OCTEON_CN58XX_PASS2 OCTEON_CN58XX_PASS2_X
+
+#define OCTEON_CN56XX_PASS1_0 0x000d0400
+#define OCTEON_CN56XX_PASS1_1 0x000d0401
+#define OCTEON_CN56XX_PASS2_0 0x000d0408
+#define OCTEON_CN56XX_PASS2_1 0x000d0409
+
+#define OCTEON_CN56XX (OCTEON_CN56XX_PASS2_0 | OM_IGNORE_REVISION)
+#define OCTEON_CN56XX_PASS1_X (OCTEON_CN56XX_PASS1_0 \
+ | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN56XX_PASS2_X (OCTEON_CN56XX_PASS2_0 \
+ | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN56XX_PASS1 OCTEON_CN56XX_PASS1_X
+#define OCTEON_CN56XX_PASS2 OCTEON_CN56XX_PASS2_X
+
+#define OCTEON_CN57XX OCTEON_CN56XX
+#define OCTEON_CN57XX_PASS1 OCTEON_CN56XX_PASS1
+#define OCTEON_CN57XX_PASS2 OCTEON_CN56XX_PASS2
+
+#define OCTEON_CN55XX OCTEON_CN56XX
+#define OCTEON_CN55XX_PASS1 OCTEON_CN56XX_PASS1
+#define OCTEON_CN55XX_PASS2 OCTEON_CN56XX_PASS2
+
+#define OCTEON_CN54XX OCTEON_CN56XX
+#define OCTEON_CN54XX_PASS1 OCTEON_CN56XX_PASS1
+#define OCTEON_CN54XX_PASS2 OCTEON_CN56XX_PASS2
+
+#define OCTEON_CN50XX_PASS1_0 0x000d0600
+
+#define OCTEON_CN50XX (OCTEON_CN50XX_PASS1_0 | OM_IGNORE_REVISION)
+#define OCTEON_CN50XX_PASS1_X (OCTEON_CN50XX_PASS1_0 \
+ | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN50XX_PASS1 OCTEON_CN50XX_PASS1_X
+
+/*
+ * NOTE: Octeon CN5000F model is not identifiable using the
+ * OCTEON_IS_MODEL() functions, but are treated as CN50XX.
+ */
+
+#define OCTEON_CN52XX_PASS1_0 0x000d0700
+#define OCTEON_CN52XX_PASS2_0 0x000d0708
+
+#define OCTEON_CN52XX (OCTEON_CN52XX_PASS2_0 | OM_IGNORE_REVISION)
+#define OCTEON_CN52XX_PASS1_X (OCTEON_CN52XX_PASS1_0 \
+ | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN52XX_PASS2_X (OCTEON_CN52XX_PASS2_0 \
+ | OM_IGNORE_MINOR_REVISION)
+#define OCTEON_CN52XX_PASS1 OCTEON_CN52XX_PASS1_X
+#define OCTEON_CN52XX_PASS2 OCTEON_CN52XX_PASS2_X
+
+/*
+ * CN3XXX models with old revision enconding
+ */
+#define OCTEON_CN38XX_PASS1 0x000d0000
+#define OCTEON_CN38XX_PASS2 0x000d0001
+#define OCTEON_CN38XX_PASS3 0x000d0003
+#define OCTEON_CN38XX (OCTEON_CN38XX_PASS3 | OM_IGNORE_REVISION)
+
+#define OCTEON_CN36XX OCTEON_CN38XX
+#define OCTEON_CN36XX_PASS2 OCTEON_CN38XX_PASS2
+#define OCTEON_CN36XX_PASS3 OCTEON_CN38XX_PASS3
+
+/* The OCTEON_CN31XX matches CN31XX models and the CN3020 */
+#define OCTEON_CN31XX_PASS1 0x000d0100
+#define OCTEON_CN31XX_PASS1_1 0x000d0102
+#define OCTEON_CN31XX (OCTEON_CN31XX_PASS1 | OM_IGNORE_REVISION)
+
+/*
+ * This model is only used for internal checks, it is not a valid
+ * model for the OCTEON_MODEL environment variable. This matches the
+ * CN3010 and CN3005 but NOT the CN3020.
+ */
+#define OCTEON_CN30XX_PASS1 0x000d0200
+#define OCTEON_CN30XX_PASS1_1 0x000d0202
+#define OCTEON_CN30XX (OCTEON_CN30XX_PASS1 | OM_IGNORE_REVISION)
+
+#define OCTEON_CN3005_PASS1 (0x000d0210 | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3005_PASS1_0 (0x000d0210 | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3005_PASS1_1 (0x000d0212 | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3005 (OCTEON_CN3005_PASS1 | OM_IGNORE_REVISION \
+ | OM_CHECK_SUBMODEL)
+
+#define OCTEON_CN3010_PASS1 (0x000d0200 | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3010_PASS1_0 (0x000d0200 | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3010_PASS1_1 (0x000d0202 | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3010 (OCTEON_CN3010_PASS1 | OM_IGNORE_REVISION \
+ | OM_CHECK_SUBMODEL)
+
+#define OCTEON_CN3020_PASS1 (0x000d0110 | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3020_PASS1_0 (0x000d0110 | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3020_PASS1_1 (0x000d0112 | OM_CHECK_SUBMODEL)
+#define OCTEON_CN3020 (OCTEON_CN3020_PASS1 | OM_IGNORE_REVISION \
+ | OM_CHECK_SUBMODEL)
+
+
+
+/* This matches the complete family of CN3xxx CPUs, and not subsequent models */
+#define OCTEON_CN3XXX (OCTEON_CN58XX_PASS1_0 \
+ | OM_MATCH_PREVIOUS_MODELS \
+ | OM_IGNORE_REVISION)
+
+/* The revision byte (low byte) has two different encodings.
+ * CN3XXX:
+ *
+ * bits
+ * <7:5>: reserved (0)
+ * <4>: alternate package
+ * <3:0>: revision
+ *
+ * CN5XXX:
+ *
+ * bits
+ * <7>: reserved (0)
+ * <6>: alternate package
+ * <5:3>: major revision
+ * <2:0>: minor revision
+ *
+ */
+
+/* Masks used for the various types of model/family/revision matching */
+#define OCTEON_38XX_FAMILY_MASK 0x00ffff00
+#define OCTEON_38XX_FAMILY_REV_MASK 0x00ffff0f
+#define OCTEON_38XX_MODEL_MASK 0x00ffff10
+#define OCTEON_38XX_MODEL_REV_MASK (OCTEON_38XX_FAMILY_REV_MASK \
+ | OCTEON_38XX_MODEL_MASK)
+
+/* CN5XXX and later use different layout of bits in the revision ID field */
+#define OCTEON_58XX_FAMILY_MASK OCTEON_38XX_FAMILY_MASK
+#define OCTEON_58XX_FAMILY_REV_MASK 0x00ffff3f
+#define OCTEON_58XX_MODEL_MASK 0x00ffffc0
+#define OCTEON_58XX_MODEL_REV_MASK (OCTEON_58XX_FAMILY_REV_MASK \
+ | OCTEON_58XX_MODEL_MASK)
+#define OCTEON_58XX_MODEL_MINOR_REV_MASK (OCTEON_58XX_MODEL_REV_MASK \
+ & 0x00fffff8)
+
+#define __OCTEON_MATCH_MASK__(x, y, z) (((x) & (z)) == ((y) & (z)))
+
+/* NOTE: This is for internal (to this file) use only. */
+static inline int __OCTEON_IS_MODEL_COMPILE__(uint32_t arg_model,
+ uint32_t chip_model)
+{
+ uint32_t rev_and_sub = OM_IGNORE_REVISION | OM_CHECK_SUBMODEL;
+
+ if ((arg_model & OCTEON_38XX_FAMILY_MASK) < OCTEON_CN58XX_PASS1_0) {
+ if (((arg_model & OM_FLAG_MASK) == rev_and_sub) &&
+ __OCTEON_MATCH_MASK__(chip_model, arg_model,
+ OCTEON_38XX_MODEL_MASK))
+ return 1;
+ if (((arg_model & OM_FLAG_MASK) == 0) &&
+ __OCTEON_MATCH_MASK__(chip_model, arg_model,
+ OCTEON_38XX_FAMILY_REV_MASK))
+ return 1;
+ if (((arg_model & OM_FLAG_MASK) == OM_IGNORE_REVISION) &&
+ __OCTEON_MATCH_MASK__(chip_model, arg_model,
+ OCTEON_38XX_FAMILY_MASK))
+ return 1;
+ if (((arg_model & OM_FLAG_MASK) == OM_CHECK_SUBMODEL) &&
+ __OCTEON_MATCH_MASK__((chip_model), (arg_model),
+ OCTEON_38XX_MODEL_REV_MASK))
+ return 1;
+ if ((arg_model & OM_MATCH_PREVIOUS_MODELS) &&
+ ((chip_model & OCTEON_38XX_MODEL_MASK) <
+ (arg_model & OCTEON_38XX_MODEL_MASK)))
+ return 1;
+ } else {
+ if (((arg_model & OM_FLAG_MASK) == rev_and_sub) &&
+ __OCTEON_MATCH_MASK__((chip_model), (arg_model),
+ OCTEON_58XX_MODEL_MASK))
+ return 1;
+ if (((arg_model & OM_FLAG_MASK) == 0) &&
+ __OCTEON_MATCH_MASK__((chip_model), (arg_model),
+ OCTEON_58XX_FAMILY_REV_MASK))
+ return 1;
+ if (((arg_model & OM_FLAG_MASK) == OM_IGNORE_MINOR_REVISION) &&
+ __OCTEON_MATCH_MASK__((chip_model), (arg_model),
+ OCTEON_58XX_MODEL_MINOR_REV_MASK))
+ return 1;
+ if (((arg_model & OM_FLAG_MASK) == OM_IGNORE_REVISION) &&
+ __OCTEON_MATCH_MASK__((chip_model), (arg_model),
+ OCTEON_58XX_FAMILY_MASK))
+ return 1;
+ if (((arg_model & OM_FLAG_MASK) == OM_CHECK_SUBMODEL) &&
+ __OCTEON_MATCH_MASK__((chip_model), (arg_model),
+ OCTEON_58XX_MODEL_REV_MASK))
+ return 1;
+ if ((arg_model & OM_MATCH_PREVIOUS_MODELS) &&
+ ((chip_model & OCTEON_58XX_MODEL_MASK) <
+ (arg_model & OCTEON_58XX_MODEL_MASK)))
+ return 1;
+ }
+ return 0;
+}
+
+/* forward declarations */
+static inline uint32_t cvmx_get_proc_id(void) __attribute__ ((pure));
+static inline uint64_t cvmx_read_csr(uint64_t csr_addr);
+
+/* NOTE: This for internal use only!!!!! */
+static inline int __octeon_is_model_runtime__(uint32_t model)
+{
+ uint32_t cpuid = cvmx_get_proc_id();
+
+ /*
+ * Check for special case of mismarked 3005 samples. We only
+ * need to check if the sub model isn't being ignored.
+ */
+ if ((model & OM_CHECK_SUBMODEL) == OM_CHECK_SUBMODEL) {
+ if (cpuid == OCTEON_CN3010_PASS1 \
+ && (cvmx_read_csr(0x80011800800007B8ull) & (1ull << 34)))
+ cpuid |= 0x10;
+ }
+ return __OCTEON_IS_MODEL_COMPILE__(model, cpuid);
+}
+
+/*
+ * The OCTEON_IS_MODEL macro should be used for all Octeon model
+ * checking done in a program. This should be kept runtime if at all
+ * possible. Any compile time (#if OCTEON_IS_MODEL) usage must be
+ * condtionalized with OCTEON_IS_COMMON_BINARY() if runtime checking
+ * support is required.
+ */
+#define OCTEON_IS_MODEL(x) __octeon_is_model_runtime__(x)
+#define OCTEON_IS_COMMON_BINARY() 1
+#undef OCTEON_MODEL
+
+const char *octeon_model_get_string(uint32_t chip_id);
+const char *octeon_model_get_string_buffer(uint32_t chip_id, char *buffer);
+
+#include "octeon-feature.h"
+
+#endif /* __OCTEON_MODEL_H__ */
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h
new file mode 100644
index 0000000..edc6760
--- /dev/null
+++ b/arch/mips/include/asm/octeon/octeon.h
@@ -0,0 +1,248 @@
+/*
+ * 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-2008 Cavium Networks
+ */
+#ifndef __ASM_OCTEON_OCTEON_H
+#define __ASM_OCTEON_OCTEON_H
+
+#include "cvmx.h"
+
+extern uint64_t octeon_bootmem_alloc_range_phys(uint64_t size,
+ uint64_t alignment,
+ uint64_t min_addr,
+ uint64_t max_addr,
+ int do_locking);
+extern void *octeon_bootmem_alloc(uint64_t size, uint64_t alignment,
+ int do_locking);
+extern void *octeon_bootmem_alloc_range(uint64_t size, uint64_t alignment,
+ uint64_t min_addr, uint64_t max_addr,
+ int do_locking);
+extern void *octeon_bootmem_alloc_named(uint64_t size, uint64_t alignment,
+ char *name);
+extern void *octeon_bootmem_alloc_named_range(uint64_t size, uint64_t min_addr,
+ uint64_t max_addr, uint64_t align,
+ char *name);
+extern void *octeon_bootmem_alloc_named_address(uint64_t size, uint64_t address,
+ char *name);
+extern int octeon_bootmem_free_named(char *name);
+extern void octeon_bootmem_lock(void);
+extern void octeon_bootmem_unlock(void);
+
+extern int octeon_is_simulation(void);
+extern int octeon_is_pci_host(void);
+extern int octeon_usb_is_ref_clk(void);
+extern uint64_t octeon_get_clock_rate(void);
+extern const char *octeon_board_type_string(void);
+extern const char *octeon_get_pci_interrupts(void);
+extern int octeon_get_southbridge_interrupt(void);
+extern int octeon_get_boot_coremask(void);
+extern int octeon_get_boot_num_arguments(void);
+extern const char *octeon_get_boot_argument(int arg);
+extern void octeon_hal_setup_reserved32(void);
+extern void octeon_user_io_init(void);
+struct octeon_cop2_state;
+extern unsigned long octeon_crypto_enable(struct octeon_cop2_state *state);
+extern void octeon_crypto_disable(struct octeon_cop2_state *state,
+ unsigned long flags);
+
+extern void octeon_init_cvmcount(void);
+
+#define OCTEON_ARGV_MAX_ARGS 64
+#define OCTOEN_SERIAL_LEN 20
+
+struct octeon_boot_descriptor {
+ /* Start of block referenced by assembly code - do not change! */
+ uint32_t desc_version;
+ uint32_t desc_size;
+ uint64_t stack_top;
+ uint64_t heap_base;
+ uint64_t heap_end;
+ /* Only used by bootloader */
+ uint64_t entry_point;
+ uint64_t desc_vaddr;
+ /* End of This block referenced by assembly code - do not change! */
+ uint32_t exception_base_addr;
+ uint32_t stack_size;
+ uint32_t heap_size;
+ /* Argc count for application. */
+ uint32_t argc;
+ uint32_t argv[OCTEON_ARGV_MAX_ARGS];
+
+#define BOOT_FLAG_INIT_CORE (1 << 0)
+#define OCTEON_BL_FLAG_DEBUG (1 << 1)
+#define OCTEON_BL_FLAG_NO_MAGIC (1 << 2)
+ /* If set, use uart1 for console */
+#define OCTEON_BL_FLAG_CONSOLE_UART1 (1 << 3)
+ /* If set, use PCI console */
+#define OCTEON_BL_FLAG_CONSOLE_PCI (1 << 4)
+ /* Call exit on break on serial port */
+#define OCTEON_BL_FLAG_BREAK (1 << 5)
+
+ uint32_t flags;
+ uint32_t core_mask;
+ /* DRAM size in megabyes. */
+ uint32_t dram_size;
+ /* physical address of free memory descriptor block. */
+ uint32_t phy_mem_desc_addr;
+ /* used to pass flags from app to debugger. */
+ uint32_t debugger_flags_base_addr;
+ /* CPU clock speed, in hz. */
+ uint32_t eclock_hz;
+ /* DRAM clock speed, in hz. */
+ uint32_t dclock_hz;
+ /* SPI4 clock in hz. */
+ uint32_t spi_clock_hz;
+ uint16_t board_type;
+ uint8_t board_rev_major;
+ uint8_t board_rev_minor;
+ uint16_t chip_type;
+ uint8_t chip_rev_major;
+ uint8_t chip_rev_minor;
+ char board_serial_number[OCTOEN_SERIAL_LEN];
+ uint8_t mac_addr_base[6];
+ uint8_t mac_addr_count;
+ uint64_t cvmx_desc_vaddr;
+};
+
+union octeon_cvmemctl {
+ uint64_t u64;
+ struct {
+ /* RO 1 = BIST fail, 0 = BIST pass */
+ uint64_t tlbbist:1;
+ /* RO 1 = BIST fail, 0 = BIST pass */
+ uint64_t l1cbist:1;
+ /* RO 1 = BIST fail, 0 = BIST pass */
+ uint64_t l1dbist:1;
+ /* RO 1 = BIST fail, 0 = BIST pass */
+ uint64_t dcmbist:1;
+ /* RO 1 = BIST fail, 0 = BIST pass */
+ uint64_t ptgbist:1;
+ /* RO 1 = BIST fail, 0 = BIST pass */
+ uint64_t wbfbist:1;
+ /* Reserved */
+ uint64_t reserved:22;
+ /* R/W If set, marked write-buffer entries time out
+ * the same as as other entries; if clear, marked
+ * write-buffer entries use the maximum timeout. */
+ uint64_t dismarkwblongto:1;
+ /* R/W If set, a merged store does not clear the
+ * write-buffer entry timeout state. */
+ uint64_t dismrgclrwbto:1;
+ /* R/W Two bits that are the MSBs of the resultant
+ * CVMSEG LM word location for an IOBDMA. The other 8
+ * bits come from the SCRADDR field of the IOBDMA. */
+ uint64_t iobdmascrmsb:2;
+ /* R/W If set, SYNCWS and SYNCS only order marked
+ * stores; if clear, SYNCWS and SYNCS only order
+ * unmarked stores. SYNCWSMARKED has no effect when
+ * DISSYNCWS is set. */
+ uint64_t syncwsmarked:1;
+ /* R/W If set, SYNCWS acts as SYNCW and SYNCS acts as
+ * SYNC. */
+ uint64_t dissyncws:1;
+ /* R/W If set, no stall happens on write buffer
+ * full. */
+ uint64_t diswbfst:1;
+ /* R/W If set (and SX set), supervisor-level
+ * loads/stores can use XKPHYS addresses with
+ * VA<48>==0 */
+ uint64_t xkmemenas:1;
+ /* R/W If set (and UX set), user-level loads/stores
+ * can use XKPHYS addresses with VA<48>==0 */
+ uint64_t xkmemenau:1;
+ /* R/W If set (and SX set), supervisor-level
+ * loads/stores can use XKPHYS addresses with
+ * VA<48>==1 */
+ uint64_t xkioenas:1;
+ /* R/W If set (and UX set), user-level loads/stores
+ * can use XKPHYS addresses with VA<48>==1 */
+ uint64_t xkioenau:1;
+ /* R/W If set, all stores act as SYNCW (NOMERGE must
+ * be set when this is set) RW, reset to 0. */
+ uint64_t allsyncw:1;
+ /* R/W If set, no stores merge, and all stores reach
+ * the coherent bus in order. */
+ uint64_t nomerge:1;
+ /* R/W Selects the bit in the counter used for DID
+ * time-outs 0 = 231, 1 = 230, 2 = 229, 3 =
+ * 214. Actual time-out is between 1x and 2x this
+ * interval. For example, with DIDTTO=3, expiration
+ * interval is between 16K and 32K. */
+ uint64_t didtto:2;
+ /* R/W If set, the (mem) CSR clock never turns off. */
+ uint64_t csrckalwys:1;
+ /* R/W If set, mclk never turns off. */
+ uint64_t mclkalwys:1;
+ /* R/W Selects the bit in the counter used for write
+ * buffer flush time-outs (WBFLT+11) is the bit
+ * position in an internal counter used to determine
+ * expiration. The write buffer expires between 1x and
+ * 2x this interval. For example, with WBFLT = 0, a
+ * write buffer expires between 2K and 4K cycles after
+ * the write buffer entry is allocated. */
+ uint64_t wbfltime:3;
+ /* R/W If set, do not put Istream in the L2 cache. */
+ uint64_t istrnol2:1;
+ /* R/W The write buffer threshold. */
+ uint64_t wbthresh:4;
+ /* Reserved */
+ uint64_t reserved2:2;
+ /* R/W If set, CVMSEG is available for loads/stores in
+ * kernel/debug mode. */
+ uint64_t cvmsegenak:1;
+ /* R/W If set, CVMSEG is available for loads/stores in
+ * supervisor mode. */
+ uint64_t cvmsegenas:1;
+ /* R/W If set, CVMSEG is available for loads/stores in
+ * user mode. */
+ uint64_t cvmsegenau:1;
+ /* R/W Size of local memory in cache blocks, 54 (6912
+ * bytes) is max legal value. */
+ uint64_t lmemsz:6;
+ } s;
+};
+
+struct octeon_cf_data {
+ unsigned long base_region_bias;
+ unsigned int base_region; /* The chip select region used by CF */
+ int is16bit; /* 0 - 8bit, !0 - 16bit */
+ int dma_engine; /* -1 for no DMA */
+};
+
+extern void octeon_write_lcd(const char *s);
+extern void octeon_check_cpu_bist(void);
+extern int octeon_get_boot_debug_flag(void);
+extern int octeon_get_boot_uart(void);
+
+struct uart_port;
+extern unsigned int octeon_serial_in(struct uart_port *, int);
+extern void octeon_serial_out(struct uart_port *, int, int);
+
+/**
+ * Write a 32bit value to the Octeon NPI register space
+ *
+ * @address: Address to write to
+ * @val: Value to write
+ */
+static inline void octeon_npi_write32(uint64_t address, uint32_t val)
+{
+ cvmx_write64_uint32(address ^ 4, val);
+ cvmx_read64_uint32(address ^ 4);
+}
+
+
+/**
+ * Read a 32bit value from the Octeon NPI register space
+ *
+ * @address: Address to read
+ * Returns The result
+ */
+static inline uint32_t octeon_npi_read32(uint64_t address)
+{
+ return cvmx_read64_uint32(address ^ 4);
+}
+
+#endif /* __ASM_OCTEON_OCTEON_H */
diff --git a/arch/mips/include/asm/processor.h b/arch/mips/include/asm/processor.h
index 18ee58e..0f926aa 100644
--- a/arch/mips/include/asm/processor.h
+++ b/arch/mips/include/asm/processor.h
@@ -118,6 +118,60 @@ union mips_watch_reg_state {
struct mips3264_watch_reg_state mips3264;
};
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+
+struct octeon_cop2_state {
+ /* DMFC2 rt, 0x0201 */
+ unsigned long cop2_crc_iv;
+ /* DMFC2 rt, 0x0202 (Set with DMTC2 rt, 0x1202) */
+ unsigned long cop2_crc_length;
+ /* DMFC2 rt, 0x0200 (set with DMTC2 rt, 0x4200) */
+ unsigned long cop2_crc_poly;
+ /* DMFC2 rt, 0x0402; DMFC2 rt, 0x040A */
+ unsigned long cop2_llm_dat[2];
+ /* DMFC2 rt, 0x0084 */
+ unsigned long cop2_3des_iv;
+ /* DMFC2 rt, 0x0080; DMFC2 rt, 0x0081; DMFC2 rt, 0x0082 */
+ unsigned long cop2_3des_key[3];
+ /* DMFC2 rt, 0x0088 (Set with DMTC2 rt, 0x0098) */
+ unsigned long cop2_3des_result;
+ /* DMFC2 rt, 0x0111 (FIXME: Read Pass1 Errata) */
+ unsigned long cop2_aes_inp0;
+ /* DMFC2 rt, 0x0102; DMFC2 rt, 0x0103 */
+ unsigned long cop2_aes_iv[2];
+ /* DMFC2 rt, 0x0104; DMFC2 rt, 0x0105; DMFC2 rt, 0x0106; DMFC2
+ * rt, 0x0107 */
+ unsigned long cop2_aes_key[4];
+ /* DMFC2 rt, 0x0110 */
+ unsigned long cop2_aes_keylen;
+ /* DMFC2 rt, 0x0100; DMFC2 rt, 0x0101 */
+ unsigned long cop2_aes_result[2];
+ /* DMFC2 rt, 0x0240; DMFC2 rt, 0x0241; DMFC2 rt, 0x0242; DMFC2
+ * rt, 0x0243; DMFC2 rt, 0x0244; DMFC2 rt, 0x0245; DMFC2 rt,
+ * 0x0246; DMFC2 rt, 0x0247; DMFC2 rt, 0x0248; DMFC2 rt,
+ * 0x0249; DMFC2 rt, 0x024A; DMFC2 rt, 0x024B; DMFC2 rt,
+ * 0x024C; DMFC2 rt, 0x024D; DMFC2 rt, 0x024E - Pass2 */
+ unsigned long cop2_hsh_datw[15];
+ /* DMFC2 rt, 0x0250; DMFC2 rt, 0x0251; DMFC2 rt, 0x0252; DMFC2
+ * rt, 0x0253; DMFC2 rt, 0x0254; DMFC2 rt, 0x0255; DMFC2 rt,
+ * 0x0256; DMFC2 rt, 0x0257 - Pass2 */
+ unsigned long cop2_hsh_ivw[8];
+ /* DMFC2 rt, 0x0258; DMFC2 rt, 0x0259 - Pass2 */
+ unsigned long cop2_gfm_mult[2];
+ /* DMFC2 rt, 0x025E - Pass2 */
+ unsigned long cop2_gfm_poly;
+ /* DMFC2 rt, 0x025A; DMFC2 rt, 0x025B - Pass2 */
+ unsigned long cop2_gfm_result[2];
+};
+#define INIT_OCTEON_COP2 {0,}
+
+struct octeon_cvmseg_state {
+ unsigned long cvmseg[CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE]
+ [cpu_dcache_line_size() / sizeof(unsigned long)];
+};
+
+#endif
+
typedef struct {
unsigned long seg;
} mm_segment_t;
@@ -160,6 +214,10 @@ struct thread_struct {
unsigned long trap_no;
unsigned long irix_trampoline; /* Wheee... */
unsigned long irix_oldctx;
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+ struct octeon_cop2_state cp2 __attribute__ ((__aligned__(128)));
+ struct octeon_cvmseg_state cvmseg __attribute__ ((__aligned__(128)));
+#endif
struct mips_abi *abi;
};
@@ -171,6 +229,13 @@ struct thread_struct {
#define FPAFF_INIT
#endif /* CONFIG_MIPS_MT_FPAFF */
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+#define OCTEON_INIT \
+ .cp2 = INIT_OCTEON_COP2,
+#else
+#define OCTEON_INIT
+#endif /* CONFIG_CPU_CAVIUM_OCTEON */
+
#define INIT_THREAD { \
/* \
* Saved main processor registers \
@@ -221,6 +286,10 @@ struct thread_struct {
.trap_no = 0, \
.irix_trampoline = 0, \
.irix_oldctx = 0, \
+ /* \
+ * Cavium Octeon specifics (null if not Octeon) \
+ */ \
+ OCTEON_INIT \
}
struct task_struct;
diff --git a/arch/mips/include/asm/ptrace.h b/arch/mips/include/asm/ptrace.h
index c2c8bac..1f30d16 100644
--- a/arch/mips/include/asm/ptrace.h
+++ b/arch/mips/include/asm/ptrace.h
@@ -48,6 +48,10 @@ struct pt_regs {
#ifdef CONFIG_MIPS_MT_SMTC
unsigned long cp0_tcstatus;
#endif /* CONFIG_MIPS_MT_SMTC */
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+ unsigned long long mpl[3]; /* MTM{0,1,2} */
+ unsigned long long mtp[3]; /* MTP{0,1,2} */
+#endif
} __attribute__ ((aligned (8)));
/* Arbitrarily choose the same ptrace numbers as used by the Sparc code. */
diff --git a/arch/mips/include/asm/smp.h b/arch/mips/include/asm/smp.h
index 86557b5..40e5ef1 100644
--- a/arch/mips/include/asm/smp.h
+++ b/arch/mips/include/asm/smp.h
@@ -37,6 +37,9 @@ extern int __cpu_logical_map[NR_CPUS];
#define SMP_RESCHEDULE_YOURSELF 0x1 /* XXX braindead */
#define SMP_CALL_FUNCTION 0x2
+/* Octeon - Tell another core to flush its icache */
+#define SMP_ICACHE_FLUSH 0x4
+
extern void asmlinkage smp_bootstrap(void);
diff --git a/arch/mips/include/asm/stackframe.h b/arch/mips/include/asm/stackframe.h
index 4c37c4e5..db0fa7b 100644
--- a/arch/mips/include/asm/stackframe.h
+++ b/arch/mips/include/asm/stackframe.h
@@ -194,6 +194,19 @@
LONG_S $31, PT_R31(sp)
ori $28, sp, _THREAD_MASK
xori $28, _THREAD_MASK
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+ .set mips64
+ pref 0, 0($28) /* Prefetch the current pointer */
+ pref 0, PT_R31(sp) /* Prefetch the $31(ra) */
+ /* The Octeon multiplier state is affected by general multiply
+ instructions. It must be saved before and kernel code might
+ corrupt it */
+ jal octeon_mult_save
+ LONG_L v1, 0($28) /* Load the current pointer */
+ /* Restore $31(ra) that was changed by the jal */
+ LONG_L ra, PT_R31(sp)
+ pref 0, 0(v1) /* Prefetch the current thread */
+#endif
.set pop
.endm
@@ -324,6 +337,10 @@
DVPE 5 # dvpe a1
jal mips_ihb
#endif /* CONFIG_MIPS_MT_SMTC */
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+ /* Restore the Octeon multiplier state */
+ jal octeon_mult_restore
+#endif
mfc0 a0, CP0_STATUS
ori a0, STATMASK
xori a0, STATMASK
diff --git a/arch/mips/include/asm/time.h b/arch/mips/include/asm/time.h
index 9601ea9..38a30d2 100644
--- a/arch/mips/include/asm/time.h
+++ b/arch/mips/include/asm/time.h
@@ -50,27 +50,35 @@ extern int (*perf_irq)(void);
/*
* Initialize the calling CPU's compare interrupt as clockevent device
*/
-#ifdef CONFIG_CEVT_R4K
-extern int mips_clockevent_init(void);
+#ifdef CONFIG_CEVT_R4K_LIB
extern unsigned int __weak get_c0_compare_int(void);
-#else
+extern int r4k_clockevent_init(void);
+#endif
+
static inline int mips_clockevent_init(void)
{
+#ifdef CONFIG_CEVT_R4K
+ return r4k_clockevent_init();
+#else
return -ENXIO;
-}
#endif
+}
/*
* Initialize the count register as a clocksource
*/
-#ifdef CONFIG_CSRC_R4K
-extern int init_mips_clocksource(void);
-#else
+#ifdef CONFIG_CSRC_R4K_LIB
+extern int init_r4k_clocksource(void);
+#endif
+
static inline int init_mips_clocksource(void)
{
+#ifdef CONFIG_CSRC_R4K
+ return init_r4k_clocksource();
+#else
return 0;
-}
#endif
+}
extern void clocksource_set_clock(struct clocksource *cs, unsigned int clock);
extern void clockevent_set_clock(struct clock_event_device *cd,
diff --git a/arch/mips/kernel/Makefile b/arch/mips/kernel/Makefile
index b1372c2..e961221 100644
--- a/arch/mips/kernel/Makefile
+++ b/arch/mips/kernel/Makefile
@@ -9,7 +9,7 @@ obj-y += cpu-probe.o branch.o entry.o genex.o irq.o process.o \
time.o topology.o traps.o unaligned.o watch.o
obj-$(CONFIG_CEVT_BCM1480) += cevt-bcm1480.o
-obj-$(CONFIG_CEVT_R4K) += cevt-r4k.o
+obj-$(CONFIG_CEVT_R4K_LIB) += cevt-r4k.o
obj-$(CONFIG_MIPS_MT_SMTC) += cevt-smtc.o
obj-$(CONFIG_CEVT_DS1287) += cevt-ds1287.o
obj-$(CONFIG_CEVT_GT641XX) += cevt-gt641xx.o
@@ -17,7 +17,7 @@ obj-$(CONFIG_CEVT_SB1250) += cevt-sb1250.o
obj-$(CONFIG_CEVT_TXX9) += cevt-txx9.o
obj-$(CONFIG_CSRC_BCM1480) += csrc-bcm1480.o
obj-$(CONFIG_CSRC_IOASIC) += csrc-ioasic.o
-obj-$(CONFIG_CSRC_R4K) += csrc-r4k.o
+obj-$(CONFIG_CSRC_R4K_LIB) += csrc-r4k.o
obj-$(CONFIG_CSRC_SB1250) += csrc-sb1250.o
obj-$(CONFIG_SYNC_R4K) += sync-r4k.o
@@ -43,6 +43,7 @@ obj-$(CONFIG_CPU_SB1) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_TX39XX) += r2300_fpu.o r2300_switch.o
obj-$(CONFIG_CPU_TX49XX) += r4k_fpu.o r4k_switch.o
obj-$(CONFIG_CPU_VR41XX) += r4k_fpu.o r4k_switch.o
+obj-$(CONFIG_CPU_CAVIUM_OCTEON) += octeon_switch.o
obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_SMP_UP) += smp-up.o
diff --git a/arch/mips/kernel/asm-offsets.c b/arch/mips/kernel/asm-offsets.c
index 7294222..c901c22 100644
--- a/arch/mips/kernel/asm-offsets.c
+++ b/arch/mips/kernel/asm-offsets.c
@@ -64,6 +64,10 @@ void output_ptreg_defines(void)
#ifdef CONFIG_MIPS_MT_SMTC
OFFSET(PT_TCSTATUS, pt_regs, cp0_tcstatus);
#endif /* CONFIG_MIPS_MT_SMTC */
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+ OFFSET(PT_MPL, pt_regs, mpl);
+ OFFSET(PT_MTP, pt_regs, mtp);
+#endif /* CONFIG_CPU_CAVIUM_OCTEON */
DEFINE(PT_SIZE, sizeof(struct pt_regs));
BLANK();
}
@@ -295,3 +299,30 @@ void output_irq_cpustat_t_defines(void)
DEFINE(IC_IRQ_CPUSTAT_T, sizeof(irq_cpustat_t));
BLANK();
}
+
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+void output_octeon_cop2_state_defines(void)
+{
+ COMMENT("Octeon specific octeon_cop2_state offsets.");
+ OFFSET(OCTEON_CP2_CRC_IV, octeon_cop2_state, cop2_crc_iv);
+ OFFSET(OCTEON_CP2_CRC_LENGTH, octeon_cop2_state, cop2_crc_length);
+ OFFSET(OCTEON_CP2_CRC_POLY, octeon_cop2_state, cop2_crc_poly);
+ OFFSET(OCTEON_CP2_LLM_DAT, octeon_cop2_state, cop2_llm_dat);
+ OFFSET(OCTEON_CP2_3DES_IV, octeon_cop2_state, cop2_3des_iv);
+ OFFSET(OCTEON_CP2_3DES_KEY, octeon_cop2_state, cop2_3des_key);
+ OFFSET(OCTEON_CP2_3DES_RESULT, octeon_cop2_state, cop2_3des_result);
+ OFFSET(OCTEON_CP2_AES_INP0, octeon_cop2_state, cop2_aes_inp0);
+ OFFSET(OCTEON_CP2_AES_IV, octeon_cop2_state, cop2_aes_iv);
+ OFFSET(OCTEON_CP2_AES_KEY, octeon_cop2_state, cop2_aes_key);
+ OFFSET(OCTEON_CP2_AES_KEYLEN, octeon_cop2_state, cop2_aes_keylen);
+ OFFSET(OCTEON_CP2_AES_RESULT, octeon_cop2_state, cop2_aes_result);
+ OFFSET(OCTEON_CP2_GFM_MULT, octeon_cop2_state, cop2_gfm_mult);
+ OFFSET(OCTEON_CP2_GFM_POLY, octeon_cop2_state, cop2_gfm_poly);
+ OFFSET(OCTEON_CP2_GFM_RESULT, octeon_cop2_state, cop2_gfm_result);
+ OFFSET(OCTEON_CP2_HSH_DATW, octeon_cop2_state, cop2_hsh_datw);
+ OFFSET(OCTEON_CP2_HSH_IVW, octeon_cop2_state, cop2_hsh_ivw);
+ OFFSET(THREAD_CP2, task_struct, thread.cp2);
+ OFFSET(THREAD_CVMSEG, task_struct, thread.cvmseg.cvmseg);
+ BLANK();
+}
+#endif
diff --git a/arch/mips/kernel/branch.c b/arch/mips/kernel/branch.c
index 6b5df8b..0176ed0 100644
--- a/arch/mips/kernel/branch.c
+++ b/arch/mips/kernel/branch.c
@@ -205,6 +205,39 @@ int __compute_return_epc(struct pt_regs *regs)
break;
}
break;
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+ case lwc2_op: /* This is bbit0 on Octeon */
+ if ((regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
+ == 0)
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+ case ldc2_op: /* This is bbit032 on Octeon */
+ if ((regs->regs[insn.i_format.rs] &
+ (1ull<<(insn.i_format.rt+32))) == 0)
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+ case swc2_op: /* This is bbit1 on Octeon */
+ if (regs->regs[insn.i_format.rs] & (1ull<<insn.i_format.rt))
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+ case sdc2_op: /* This is bbit132 on Octeon */
+ if (regs->regs[insn.i_format.rs] &
+ (1ull<<(insn.i_format.rt+32)))
+ epc = epc + 4 + (insn.i_format.simmediate << 2);
+ else
+ epc += 8;
+ regs->cp0_epc = epc;
+ break;
+#endif
}
return 0;
diff --git a/arch/mips/kernel/cevt-r4k.c b/arch/mips/kernel/cevt-r4k.c
index e1ec83b..0015e44 100644
--- a/arch/mips/kernel/cevt-r4k.c
+++ b/arch/mips/kernel/cevt-r4k.c
@@ -160,7 +160,7 @@ int c0_compare_int_usable(void)
#ifndef CONFIG_MIPS_MT_SMTC
-int __cpuinit mips_clockevent_init(void)
+int __cpuinit r4k_clockevent_init(void)
{
uint64_t mips_freq = mips_hpt_frequency;
unsigned int cpu = smp_processor_id();
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index c9207b5..a7162a4 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -96,6 +96,9 @@ int allow_au1k_wait;
static void au1k_wait(void)
{
+ if (!allow_au1k_wait)
+ return;
+
/* using the wait instruction makes CP0 counter unusable */
__asm__(" .set mips3 \n"
" cache 0x14, 0(%0) \n"
@@ -154,6 +157,7 @@ void __init check_wait(void)
case CPU_25KF:
case CPU_PR4450:
case CPU_BCM3302:
+ case CPU_CAVIUM_OCTEON:
cpu_wait = r4k_wait;
break;
@@ -185,8 +189,7 @@ void __init check_wait(void)
case CPU_AU1200:
case CPU_AU1210:
case CPU_AU1250:
- if (allow_au1k_wait)
- cpu_wait = au1k_wait;
+ cpu_wait = au1k_wait;
break;
case CPU_20KC:
/*
@@ -875,6 +878,27 @@ static inline void cpu_probe_broadcom(struct cpuinfo_mips *c, unsigned int cpu)
}
}
+static inline void cpu_probe_cavium(struct cpuinfo_mips *c, unsigned int cpu)
+{
+ decode_configs(c);
+ switch (c->processor_id & 0xff00) {
+ case PRID_IMP_CAVIUM_CN38XX:
+ case PRID_IMP_CAVIUM_CN31XX:
+ case PRID_IMP_CAVIUM_CN30XX:
+ case PRID_IMP_CAVIUM_CN58XX:
+ case PRID_IMP_CAVIUM_CN56XX:
+ case PRID_IMP_CAVIUM_CN50XX:
+ case PRID_IMP_CAVIUM_CN52XX:
+ c->cputype = CPU_CAVIUM_OCTEON;
+ __cpu_name[cpu] = "Cavium Octeon";
+ break;
+ default:
+ printk(KERN_INFO "Unknown Octeon chip!\n");
+ c->cputype = CPU_UNKNOWN;
+ break;
+ }
+}
+
const char *__cpu_name[NR_CPUS];
__cpuinit void cpu_probe(void)
@@ -909,6 +933,9 @@ __cpuinit void cpu_probe(void)
case PRID_COMP_NXP:
cpu_probe_nxp(c, cpu);
break;
+ case PRID_COMP_CAVIUM:
+ cpu_probe_cavium(c, cpu);
+ break;
}
BUG_ON(!__cpu_name[cpu]);
diff --git a/arch/mips/kernel/csrc-r4k.c b/arch/mips/kernel/csrc-r4k.c
index 74fb745..f1a2893 100644
--- a/arch/mips/kernel/csrc-r4k.c
+++ b/arch/mips/kernel/csrc-r4k.c
@@ -22,7 +22,7 @@ static struct clocksource clocksource_mips = {
.flags = CLOCK_SOURCE_IS_CONTINUOUS,
};
-int __init init_mips_clocksource(void)
+int __init init_r4k_clocksource(void)
{
if (!cpu_has_counter || !mips_hpt_frequency)
return -ENXIO;
diff --git a/arch/mips/kernel/genex.S b/arch/mips/kernel/genex.S
index 757d48f..fb6f731 100644
--- a/arch/mips/kernel/genex.S
+++ b/arch/mips/kernel/genex.S
@@ -385,10 +385,14 @@ NESTED(nmi_handler, PT_SIZE, sp)
.endm
.macro __build_clear_fpe
+ .set push
+ /* gas fails to assemble cfc1 for some archs (octeon).*/ \
+ .set mips1
cfc1 a1, fcr31
li a2, ~(0x3f << 12)
and a2, a1
ctc1 a2, fcr31
+ .set pop
TRACE_IRQS_ON
STI
.endm
diff --git a/arch/mips/kernel/irq-gic.c b/arch/mips/kernel/irq-gic.c
index 494a49a..87deb8f 100644
--- a/arch/mips/kernel/irq-gic.c
+++ b/arch/mips/kernel/irq-gic.c
@@ -187,7 +187,7 @@ static void gic_set_affinity(unsigned int irq, const struct cpumask *cpumask)
set_bit(irq, pcpu_masks[first_cpu(tmp)].pcpu_mask);
}
- irq_desc[irq].affinity = *cpumask;
+ cpumask_copy(irq_desc[irq].affinity, cpumask);
spin_unlock_irqrestore(&gic_lock, flags);
}
diff --git a/arch/mips/kernel/irq.c b/arch/mips/kernel/irq.c
index 4b4007b..a0ff2b6 100644
--- a/arch/mips/kernel/irq.c
+++ b/arch/mips/kernel/irq.c
@@ -111,6 +111,7 @@ int show_interrupts(struct seq_file *p, void *v)
seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]);
#endif
seq_printf(p, " %14s", irq_desc[i].chip->name);
+ seq_printf(p, "-%-8s", irq_desc[i].name);
seq_printf(p, " %s", action->name);
for (action=action->next; action; action = action->next)
diff --git a/arch/mips/kernel/octeon_switch.S b/arch/mips/kernel/octeon_switch.S
new file mode 100644
index 0000000..d523896
--- /dev/null
+++ b/arch/mips/kernel/octeon_switch.S
@@ -0,0 +1,506 @@
+/*
+ * 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, 1995, 1996, 1998, 1999, 2002, 2003 Ralf Baechle
+ * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
+ * Copyright (C) 1994, 1995, 1996, by Andreas Busse
+ * Copyright (C) 1999 Silicon Graphics, Inc.
+ * Copyright (C) 2000 MIPS Technologies, Inc.
+ * written by Carsten Langgaard, carstenl@mips.com
+ */
+#include <asm/asm.h>
+#include <asm/cachectl.h>
+#include <asm/fpregdef.h>
+#include <asm/mipsregs.h>
+#include <asm/asm-offsets.h>
+#include <asm/page.h>
+#include <asm/pgtable-bits.h>
+#include <asm/regdef.h>
+#include <asm/stackframe.h>
+#include <asm/thread_info.h>
+
+#include <asm/asmmacro.h>
+
+/*
+ * Offset to the current process status flags, the first 32 bytes of the
+ * stack are not used.
+ */
+#define ST_OFF (_THREAD_SIZE - 32 - PT_SIZE + PT_STATUS)
+
+/*
+ * task_struct *resume(task_struct *prev, task_struct *next,
+ * struct thread_info *next_ti)
+ */
+ .align 7
+ LEAF(resume)
+ .set arch=octeon
+#ifndef CONFIG_CPU_HAS_LLSC
+ sw zero, ll_bit
+#endif
+ mfc0 t1, CP0_STATUS
+ LONG_S t1, THREAD_STATUS(a0)
+ cpu_save_nonscratch a0
+ LONG_S ra, THREAD_REG31(a0)
+
+ /* check if we need to save COP2 registers */
+ PTR_L t2, TASK_THREAD_INFO(a0)
+ LONG_L t0, ST_OFF(t2)
+ bbit0 t0, 30, 1f
+
+ /* Disable COP2 in the stored process state */
+ li t1, ST0_CU2
+ xor t0, t1
+ LONG_S t0, ST_OFF(t2)
+
+ /* Enable COP2 so we can save it */
+ mfc0 t0, CP0_STATUS
+ or t0, t1
+ mtc0 t0, CP0_STATUS
+
+ /* Save COP2 */
+ daddu a0, THREAD_CP2
+ jal octeon_cop2_save
+ dsubu a0, THREAD_CP2
+
+ /* Disable COP2 now that we are done */
+ mfc0 t0, CP0_STATUS
+ li t1, ST0_CU2
+ xor t0, t1
+ mtc0 t0, CP0_STATUS
+
+1:
+#if CONFIG_CAVIUM_OCTEON_CVMSEG_SIZE > 0
+ /* Check if we need to store CVMSEG state */
+ mfc0 t0, $11,7 /* CvmMemCtl */
+ bbit0 t0, 6, 3f /* Is user access enabled? */
+
+ /* Store the CVMSEG state */
+ /* Extract the size of CVMSEG */
+ andi t0, 0x3f
+ /* Multiply * (cache line size/sizeof(long)/2) */
+ sll t0, 7-LONGLOG-1
+ li t1, -32768 /* Base address of CVMSEG */
+ LONG_ADDI t2, a0, THREAD_CVMSEG /* Where to store CVMSEG to */
+ synciobdma
+2:
+ .set noreorder
+ LONG_L t8, 0(t1) /* Load from CVMSEG */
+ subu t0, 1 /* Decrement loop var */
+ LONG_L t9, LONGSIZE(t1)/* Load from CVMSEG */
+ LONG_ADDU t1, LONGSIZE*2 /* Increment loc in CVMSEG */
+ LONG_S t8, 0(t2) /* Store CVMSEG to thread storage */
+ LONG_ADDU t2, LONGSIZE*2 /* Increment loc in thread storage */
+ bnez t0, 2b /* Loop until we've copied it all */
+ LONG_S t9, -LONGSIZE(t2)/* Store CVMSEG to thread storage */
+ .set reorder
+
+ /* Disable access to CVMSEG */
+ mfc0 t0, $11,7 /* CvmMemCtl */
+ xori t0, t0, 0x40 /* Bit 6 is CVMSEG user enable */
+ mtc0 t0, $11,7 /* CvmMemCtl */
+#endif
+3:
+ /*
+ * The order of restoring the registers takes care of the race
+ * updating $28, $29 and kernelsp without disabling ints.
+ */
+ move $28, a2
+ cpu_restore_nonscratch a1
+
+#if (_THREAD_SIZE - 32) < 0x8000
+ PTR_ADDIU t0, $28, _THREAD_SIZE - 32
+#else
+ PTR_LI t0, _THREAD_SIZE - 32
+ PTR_ADDU t0, $28
+#endif
+ set_saved_sp t0, t1, t2
+
+ mfc0 t1, CP0_STATUS /* Do we really need this? */
+ li a3, 0xff01
+ and t1, a3
+ LONG_L a2, THREAD_STATUS(a1)
+ nor a3, $0, a3
+ and a2, a3
+ or a2, t1
+ mtc0 a2, CP0_STATUS
+ move v0, a0
+ jr ra
+ END(resume)
+
+/*
+ * void octeon_cop2_save(struct octeon_cop2_state *a0)
+ */
+ .align 7
+ LEAF(octeon_cop2_save)
+
+ dmfc0 t9, $9,7 /* CvmCtl register. */
+
+ /* Save the COP2 CRC state */
+ dmfc2 t0, 0x0201
+ dmfc2 t1, 0x0202
+ dmfc2 t2, 0x0200
+ sd t0, OCTEON_CP2_CRC_IV(a0)
+ sd t1, OCTEON_CP2_CRC_LENGTH(a0)
+ sd t2, OCTEON_CP2_CRC_POLY(a0)
+ /* Skip next instructions if CvmCtl[NODFA_CP2] set */
+ bbit1 t9, 28, 1f
+
+ /* Save the LLM state */
+ dmfc2 t0, 0x0402
+ dmfc2 t1, 0x040A
+ sd t0, OCTEON_CP2_LLM_DAT(a0)
+ sd t1, OCTEON_CP2_LLM_DAT+8(a0)
+
+1: bbit1 t9, 26, 3f /* done if CvmCtl[NOCRYPTO] set */
+
+ /* Save the COP2 crypto state */
+ /* this part is mostly common to both pass 1 and later revisions */
+ dmfc2 t0, 0x0084
+ dmfc2 t1, 0x0080
+ dmfc2 t2, 0x0081
+ dmfc2 t3, 0x0082
+ sd t0, OCTEON_CP2_3DES_IV(a0)
+ dmfc2 t0, 0x0088
+ sd t1, OCTEON_CP2_3DES_KEY(a0)
+ dmfc2 t1, 0x0111 /* only necessary for pass 1 */
+ sd t2, OCTEON_CP2_3DES_KEY+8(a0)
+ dmfc2 t2, 0x0102
+ sd t3, OCTEON_CP2_3DES_KEY+16(a0)
+ dmfc2 t3, 0x0103
+ sd t0, OCTEON_CP2_3DES_RESULT(a0)
+ dmfc2 t0, 0x0104
+ sd t1, OCTEON_CP2_AES_INP0(a0) /* only necessary for pass 1 */
+ dmfc2 t1, 0x0105
+ sd t2, OCTEON_CP2_AES_IV(a0)
+ dmfc2 t2, 0x0106
+ sd t3, OCTEON_CP2_AES_IV+8(a0)
+ dmfc2 t3, 0x0107
+ sd t0, OCTEON_CP2_AES_KEY(a0)
+ dmfc2 t0, 0x0110
+ sd t1, OCTEON_CP2_AES_KEY+8(a0)
+ dmfc2 t1, 0x0100
+ sd t2, OCTEON_CP2_AES_KEY+16(a0)
+ dmfc2 t2, 0x0101
+ sd t3, OCTEON_CP2_AES_KEY+24(a0)
+ mfc0 t3, $15,0 /* Get the processor ID register */
+ sd t0, OCTEON_CP2_AES_KEYLEN(a0)
+ li t0, 0x000d0000 /* This is the processor ID of Octeon Pass1 */
+ sd t1, OCTEON_CP2_AES_RESULT(a0)
+ sd t2, OCTEON_CP2_AES_RESULT+8(a0)
+ /* Skip to the Pass1 version of the remainder of the COP2 state */
+ beq t3, t0, 2f
+
+ /* the non-pass1 state when !CvmCtl[NOCRYPTO] */
+ dmfc2 t1, 0x0240
+ dmfc2 t2, 0x0241
+ dmfc2 t3, 0x0242
+ dmfc2 t0, 0x0243
+ sd t1, OCTEON_CP2_HSH_DATW(a0)
+ dmfc2 t1, 0x0244
+ sd t2, OCTEON_CP2_HSH_DATW+8(a0)
+ dmfc2 t2, 0x0245
+ sd t3, OCTEON_CP2_HSH_DATW+16(a0)
+ dmfc2 t3, 0x0246
+ sd t0, OCTEON_CP2_HSH_DATW+24(a0)
+ dmfc2 t0, 0x0247
+ sd t1, OCTEON_CP2_HSH_DATW+32(a0)
+ dmfc2 t1, 0x0248
+ sd t2, OCTEON_CP2_HSH_DATW+40(a0)
+ dmfc2 t2, 0x0249
+ sd t3, OCTEON_CP2_HSH_DATW+48(a0)
+ dmfc2 t3, 0x024A
+ sd t0, OCTEON_CP2_HSH_DATW+56(a0)
+ dmfc2 t0, 0x024B
+ sd t1, OCTEON_CP2_HSH_DATW+64(a0)
+ dmfc2 t1, 0x024C
+ sd t2, OCTEON_CP2_HSH_DATW+72(a0)
+ dmfc2 t2, 0x024D
+ sd t3, OCTEON_CP2_HSH_DATW+80(a0)
+ dmfc2 t3, 0x024E
+ sd t0, OCTEON_CP2_HSH_DATW+88(a0)
+ dmfc2 t0, 0x0250
+ sd t1, OCTEON_CP2_HSH_DATW+96(a0)
+ dmfc2 t1, 0x0251
+ sd t2, OCTEON_CP2_HSH_DATW+104(a0)
+ dmfc2 t2, 0x0252
+ sd t3, OCTEON_CP2_HSH_DATW+112(a0)
+ dmfc2 t3, 0x0253
+ sd t0, OCTEON_CP2_HSH_IVW(a0)
+ dmfc2 t0, 0x0254
+ sd t1, OCTEON_CP2_HSH_IVW+8(a0)
+ dmfc2 t1, 0x0255
+ sd t2, OCTEON_CP2_HSH_IVW+16(a0)
+ dmfc2 t2, 0x0256
+ sd t3, OCTEON_CP2_HSH_IVW+24(a0)
+ dmfc2 t3, 0x0257
+ sd t0, OCTEON_CP2_HSH_IVW+32(a0)
+ dmfc2 t0, 0x0258
+ sd t1, OCTEON_CP2_HSH_IVW+40(a0)
+ dmfc2 t1, 0x0259
+ sd t2, OCTEON_CP2_HSH_IVW+48(a0)
+ dmfc2 t2, 0x025E
+ sd t3, OCTEON_CP2_HSH_IVW+56(a0)
+ dmfc2 t3, 0x025A
+ sd t0, OCTEON_CP2_GFM_MULT(a0)
+ dmfc2 t0, 0x025B
+ sd t1, OCTEON_CP2_GFM_MULT+8(a0)
+ sd t2, OCTEON_CP2_GFM_POLY(a0)
+ sd t3, OCTEON_CP2_GFM_RESULT(a0)
+ sd t0, OCTEON_CP2_GFM_RESULT+8(a0)
+ jr ra
+
+2: /* pass 1 special stuff when !CvmCtl[NOCRYPTO] */
+ dmfc2 t3, 0x0040
+ dmfc2 t0, 0x0041
+ dmfc2 t1, 0x0042
+ dmfc2 t2, 0x0043
+ sd t3, OCTEON_CP2_HSH_DATW(a0)
+ dmfc2 t3, 0x0044
+ sd t0, OCTEON_CP2_HSH_DATW+8(a0)
+ dmfc2 t0, 0x0045
+ sd t1, OCTEON_CP2_HSH_DATW+16(a0)
+ dmfc2 t1, 0x0046
+ sd t2, OCTEON_CP2_HSH_DATW+24(a0)
+ dmfc2 t2, 0x0048
+ sd t3, OCTEON_CP2_HSH_DATW+32(a0)
+ dmfc2 t3, 0x0049
+ sd t0, OCTEON_CP2_HSH_DATW+40(a0)
+ dmfc2 t0, 0x004A
+ sd t1, OCTEON_CP2_HSH_DATW+48(a0)
+ sd t2, OCTEON_CP2_HSH_IVW(a0)
+ sd t3, OCTEON_CP2_HSH_IVW+8(a0)
+ sd t0, OCTEON_CP2_HSH_IVW+16(a0)
+
+3: /* pass 1 or CvmCtl[NOCRYPTO] set */
+ jr ra
+ END(octeon_cop2_save)
+
+/*
+ * void octeon_cop2_restore(struct octeon_cop2_state *a0)
+ */
+ .align 7
+ .set push
+ .set noreorder
+ LEAF(octeon_cop2_restore)
+ /* First cache line was prefetched before the call */
+ pref 4, 128(a0)
+ dmfc0 t9, $9,7 /* CvmCtl register. */
+
+ pref 4, 256(a0)
+ ld t0, OCTEON_CP2_CRC_IV(a0)
+ pref 4, 384(a0)
+ ld t1, OCTEON_CP2_CRC_LENGTH(a0)
+ ld t2, OCTEON_CP2_CRC_POLY(a0)
+
+ /* Restore the COP2 CRC state */
+ dmtc2 t0, 0x0201
+ dmtc2 t1, 0x1202
+ bbit1 t9, 28, 2f /* Skip LLM if CvmCtl[NODFA_CP2] is set */
+ dmtc2 t2, 0x4200
+
+ /* Restore the LLM state */
+ ld t0, OCTEON_CP2_LLM_DAT(a0)
+ ld t1, OCTEON_CP2_LLM_DAT+8(a0)
+ dmtc2 t0, 0x0402
+ dmtc2 t1, 0x040A
+
+2:
+ bbit1 t9, 26, done_restore /* done if CvmCtl[NOCRYPTO] set */
+ nop
+
+ /* Restore the COP2 crypto state common to pass 1 and pass 2 */
+ ld t0, OCTEON_CP2_3DES_IV(a0)
+ ld t1, OCTEON_CP2_3DES_KEY(a0)
+ ld t2, OCTEON_CP2_3DES_KEY+8(a0)
+ dmtc2 t0, 0x0084
+ ld t0, OCTEON_CP2_3DES_KEY+16(a0)
+ dmtc2 t1, 0x0080
+ ld t1, OCTEON_CP2_3DES_RESULT(a0)
+ dmtc2 t2, 0x0081
+ ld t2, OCTEON_CP2_AES_INP0(a0) /* only really needed for pass 1 */
+ dmtc2 t0, 0x0082
+ ld t0, OCTEON_CP2_AES_IV(a0)
+ dmtc2 t1, 0x0098
+ ld t1, OCTEON_CP2_AES_IV+8(a0)
+ dmtc2 t2, 0x010A /* only really needed for pass 1 */
+ ld t2, OCTEON_CP2_AES_KEY(a0)
+ dmtc2 t0, 0x0102
+ ld t0, OCTEON_CP2_AES_KEY+8(a0)
+ dmtc2 t1, 0x0103
+ ld t1, OCTEON_CP2_AES_KEY+16(a0)
+ dmtc2 t2, 0x0104
+ ld t2, OCTEON_CP2_AES_KEY+24(a0)
+ dmtc2 t0, 0x0105
+ ld t0, OCTEON_CP2_AES_KEYLEN(a0)
+ dmtc2 t1, 0x0106
+ ld t1, OCTEON_CP2_AES_RESULT(a0)
+ dmtc2 t2, 0x0107
+ ld t2, OCTEON_CP2_AES_RESULT+8(a0)
+ mfc0 t3, $15,0 /* Get the processor ID register */
+ dmtc2 t0, 0x0110
+ li t0, 0x000d0000 /* This is the processor ID of Octeon Pass1 */
+ dmtc2 t1, 0x0100
+ bne t0, t3, 3f /* Skip the next stuff for non-pass1 */
+ dmtc2 t2, 0x0101
+
+ /* this code is specific for pass 1 */
+ ld t0, OCTEON_CP2_HSH_DATW(a0)
+ ld t1, OCTEON_CP2_HSH_DATW+8(a0)
+ ld t2, OCTEON_CP2_HSH_DATW+16(a0)
+ dmtc2 t0, 0x0040
+ ld t0, OCTEON_CP2_HSH_DATW+24(a0)
+ dmtc2 t1, 0x0041
+ ld t1, OCTEON_CP2_HSH_DATW+32(a0)
+ dmtc2 t2, 0x0042
+ ld t2, OCTEON_CP2_HSH_DATW+40(a0)
+ dmtc2 t0, 0x0043
+ ld t0, OCTEON_CP2_HSH_DATW+48(a0)
+ dmtc2 t1, 0x0044
+ ld t1, OCTEON_CP2_HSH_IVW(a0)
+ dmtc2 t2, 0x0045
+ ld t2, OCTEON_CP2_HSH_IVW+8(a0)
+ dmtc2 t0, 0x0046
+ ld t0, OCTEON_CP2_HSH_IVW+16(a0)
+ dmtc2 t1, 0x0048
+ dmtc2 t2, 0x0049
+ b done_restore /* unconditional branch */
+ dmtc2 t0, 0x004A
+
+3: /* this is post-pass1 code */
+ ld t2, OCTEON_CP2_HSH_DATW(a0)
+ ld t0, OCTEON_CP2_HSH_DATW+8(a0)
+ ld t1, OCTEON_CP2_HSH_DATW+16(a0)
+ dmtc2 t2, 0x0240
+ ld t2, OCTEON_CP2_HSH_DATW+24(a0)
+ dmtc2 t0, 0x0241
+ ld t0, OCTEON_CP2_HSH_DATW+32(a0)
+ dmtc2 t1, 0x0242
+ ld t1, OCTEON_CP2_HSH_DATW+40(a0)
+ dmtc2 t2, 0x0243
+ ld t2, OCTEON_CP2_HSH_DATW+48(a0)
+ dmtc2 t0, 0x0244
+ ld t0, OCTEON_CP2_HSH_DATW+56(a0)
+ dmtc2 t1, 0x0245
+ ld t1, OCTEON_CP2_HSH_DATW+64(a0)
+ dmtc2 t2, 0x0246
+ ld t2, OCTEON_CP2_HSH_DATW+72(a0)
+ dmtc2 t0, 0x0247
+ ld t0, OCTEON_CP2_HSH_DATW+80(a0)
+ dmtc2 t1, 0x0248
+ ld t1, OCTEON_CP2_HSH_DATW+88(a0)
+ dmtc2 t2, 0x0249
+ ld t2, OCTEON_CP2_HSH_DATW+96(a0)
+ dmtc2 t0, 0x024A
+ ld t0, OCTEON_CP2_HSH_DATW+104(a0)
+ dmtc2 t1, 0x024B
+ ld t1, OCTEON_CP2_HSH_DATW+112(a0)
+ dmtc2 t2, 0x024C
+ ld t2, OCTEON_CP2_HSH_IVW(a0)
+ dmtc2 t0, 0x024D
+ ld t0, OCTEON_CP2_HSH_IVW+8(a0)
+ dmtc2 t1, 0x024E
+ ld t1, OCTEON_CP2_HSH_IVW+16(a0)
+ dmtc2 t2, 0x0250
+ ld t2, OCTEON_CP2_HSH_IVW+24(a0)
+ dmtc2 t0, 0x0251
+ ld t0, OCTEON_CP2_HSH_IVW+32(a0)
+ dmtc2 t1, 0x0252
+ ld t1, OCTEON_CP2_HSH_IVW+40(a0)
+ dmtc2 t2, 0x0253
+ ld t2, OCTEON_CP2_HSH_IVW+48(a0)
+ dmtc2 t0, 0x0254
+ ld t0, OCTEON_CP2_HSH_IVW+56(a0)
+ dmtc2 t1, 0x0255
+ ld t1, OCTEON_CP2_GFM_MULT(a0)
+ dmtc2 t2, 0x0256
+ ld t2, OCTEON_CP2_GFM_MULT+8(a0)
+ dmtc2 t0, 0x0257
+ ld t0, OCTEON_CP2_GFM_POLY(a0)
+ dmtc2 t1, 0x0258
+ ld t1, OCTEON_CP2_GFM_RESULT(a0)
+ dmtc2 t2, 0x0259
+ ld t2, OCTEON_CP2_GFM_RESULT+8(a0)
+ dmtc2 t0, 0x025E
+ dmtc2 t1, 0x025A
+ dmtc2 t2, 0x025B
+
+done_restore:
+ jr ra
+ nop
+ END(octeon_cop2_restore)
+ .set pop
+
+/*
+ * void octeon_mult_save()
+ * sp is assumed to point to a struct pt_regs
+ *
+ * NOTE: This is called in SAVE_SOME in stackframe.h. It can only
+ * safely modify k0 and k1.
+ */
+ .align 7
+ .set push
+ .set noreorder
+ LEAF(octeon_mult_save)
+ dmfc0 k0, $9,7 /* CvmCtl register. */
+ bbit1 k0, 27, 1f /* Skip CvmCtl[NOMUL] */
+ nop
+
+ /* Save the multiplier state */
+ v3mulu k0, $0, $0
+ v3mulu k1, $0, $0
+ sd k0, PT_MTP(sp) /* PT_MTP has P0 */
+ v3mulu k0, $0, $0
+ sd k1, PT_MTP+8(sp) /* PT_MTP+8 has P1 */
+ ori k1, $0, 1
+ v3mulu k1, k1, $0
+ sd k0, PT_MTP+16(sp) /* PT_MTP+16 has P2 */
+ v3mulu k0, $0, $0
+ sd k1, PT_MPL(sp) /* PT_MPL has MPL0 */
+ v3mulu k1, $0, $0
+ sd k0, PT_MPL+8(sp) /* PT_MPL+8 has MPL1 */
+ jr ra
+ sd k1, PT_MPL+16(sp) /* PT_MPL+16 has MPL2 */
+
+1: /* Resume here if CvmCtl[NOMUL] */
+ jr ra
+ END(octeon_mult_save)
+ .set pop
+
+/*
+ * void octeon_mult_restore()
+ * sp is assumed to point to a struct pt_regs
+ *
+ * NOTE: This is called in RESTORE_SOME in stackframe.h.
+ */
+ .align 7
+ .set push
+ .set noreorder
+ LEAF(octeon_mult_restore)
+ dmfc0 k1, $9,7 /* CvmCtl register. */
+ ld v0, PT_MPL(sp) /* MPL0 */
+ ld v1, PT_MPL+8(sp) /* MPL1 */
+ ld k0, PT_MPL+16(sp) /* MPL2 */
+ bbit1 k1, 27, 1f /* Skip CvmCtl[NOMUL] */
+ /* Normally falls through, so no time wasted here */
+ nop
+
+ /* Restore the multiplier state */
+ ld k1, PT_MTP+16(sp) /* P2 */
+ MTM0 v0 /* MPL0 */
+ ld v0, PT_MTP+8(sp) /* P1 */
+ MTM1 v1 /* MPL1 */
+ ld v1, PT_MTP(sp) /* P0 */
+ MTM2 k0 /* MPL2 */
+ MTP2 k1 /* P2 */
+ MTP1 v0 /* P1 */
+ jr ra
+ MTP0 v1 /* P0 */
+
+1: /* Resume here if CvmCtl[NOMUL] */
+ jr ra
+ nop
+ END(octeon_mult_restore)
+ .set pop
+
diff --git a/arch/mips/kernel/ptrace32.c b/arch/mips/kernel/ptrace32.c
index 1ca3410..c4f9ac1 100644
--- a/arch/mips/kernel/ptrace32.c
+++ b/arch/mips/kernel/ptrace32.c
@@ -49,19 +49,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
int ret;
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 int 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 int __user *) (unsigned long) data);
- break;
- }
/*
* Read 4 bytes of the other process' storage
@@ -208,16 +195,6 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
break;
}
- /* when 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 4 bytes into the other process' storage
* data is the 4 bytes that the user wants written
@@ -332,50 +309,11 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
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;
- 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;
- 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;
- wake_up_process(child);
- break;
-
case PTRACE_GET_THREAD_AREA:
ret = put_user(task_thread_info(child)->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(task_thread_info(child)->tp_value,
(unsigned long __user *) (unsigned long) data);
@@ -392,7 +330,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
break;
default:
- ret = ptrace_request(child, request, addr, data);
+ ret = compat_ptrace_request(child, request, addr, data);
break;
}
out:
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index b6cca01..5f5af7d 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -686,7 +686,7 @@ void smtc_forward_irq(unsigned int irq)
* and efficiency, we just pick the easiest one to find.
*/
- target = first_cpu(irq_desc[irq].affinity);
+ target = cpumask_first(irq_desc[irq].affinity);
/*
* We depend on the platform code to have correctly processed
@@ -921,11 +921,13 @@ void ipi_decode(struct smtc_ipi *pipi)
struct clock_event_device *cd;
void *arg_copy = pipi->arg;
int type_copy = pipi->type;
+ int irq = MIPS_CPU_IRQ_BASE + 1;
+
smtc_ipi_nq(&freeIPIq, pipi);
switch (type_copy) {
case SMTC_CLOCK_TICK:
irq_enter();
- kstat_this_cpu.irqs[MIPS_CPU_IRQ_BASE + 1]++;
+ kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
cd = &per_cpu(mips_clockevent_device, cpu);
cd->event_handler(cd);
irq_exit();
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index 3530561..f6083c6 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -47,6 +47,7 @@
#include <asm/mmu_context.h>
#include <asm/types.h>
#include <asm/stacktrace.h>
+#include <asm/irq.h>
extern void check_wait(void);
extern asmlinkage void r4k_wait(void);
@@ -78,6 +79,10 @@ extern asmlinkage void handle_reserved(void);
extern int fpu_emulator_cop1Handler(struct pt_regs *xcp,
struct mips_fpu_struct *ctx, int has_fpu);
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+extern asmlinkage void octeon_cop2_restore(struct octeon_cop2_state *task);
+#endif
+
void (*board_be_init)(void);
int (*board_be_handler)(struct pt_regs *regs, int is_fixup);
void (*board_nmi_handler_setup)(void);
@@ -860,6 +865,7 @@ asmlinkage void do_cpu(struct pt_regs *regs)
unsigned int opcode;
unsigned int cpid;
int status;
+ unsigned long __maybe_unused flags;
die_if_kernel("do_cpu invoked from kernel context!", regs);
@@ -915,6 +921,17 @@ asmlinkage void do_cpu(struct pt_regs *regs)
return;
case 2:
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+ prefetch(&current->thread.cp2);
+ local_irq_save(flags);
+ KSTK_STATUS(current) |= ST0_CU2;
+ status = read_c0_status();
+ write_c0_status(status | ST0_CU2);
+ octeon_cop2_restore(&(current->thread.cp2));
+ write_c0_status(status & ~ST0_CU2);
+ local_irq_restore(flags);
+ return;
+#endif
case 3:
break;
}
@@ -1488,6 +1505,10 @@ void __cpuinit per_cpu_trap_init(void)
write_c0_hwrena(enable);
}
+#ifdef CONFIG_CPU_CAVIUM_OCTEON
+ write_c0_hwrena(0xc000000f); /* Octeon has register 30 and 31 */
+#endif
+
#ifdef CONFIG_MIPS_MT_SMTC
if (!secondaryTC) {
#endif /* CONFIG_MIPS_MT_SMTC */
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index dbcf651..c13c7ad 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_CPU_SB1) += dump_tlb.o
obj-$(CONFIG_CPU_TX39XX) += r3k_dump_tlb.o
obj-$(CONFIG_CPU_TX49XX) += dump_tlb.o
obj-$(CONFIG_CPU_VR41XX) += dump_tlb.o
+obj-$(CONFIG_CPU_CAVIUM_OCTEON) += dump_tlb.o
# libgcc-style stuff needed in the kernel
obj-y += ashldi3.o ashrdi3.o cmpdi2.o lshrdi3.o ucmpdi2.o
diff --git a/arch/mips/mm/Makefile b/arch/mips/mm/Makefile
index 95ba32b..d7ec955 100644
--- a/arch/mips/mm/Makefile
+++ b/arch/mips/mm/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_CPU_SB1) += c-r4k.o cerr-sb1.o cex-sb1.o tlb-r4k.o
obj-$(CONFIG_CPU_TX39XX) += c-tx39.o tlb-r3k.o
obj-$(CONFIG_CPU_TX49XX) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_VR41XX) += c-r4k.o cex-gen.o tlb-r4k.o
+obj-$(CONFIG_CPU_CAVIUM_OCTEON) += c-octeon.o cex-oct.o tlb-r4k.o
obj-$(CONFIG_IP22_CPU_SCACHE) += sc-ip22.o
obj-$(CONFIG_R5000_CPU_SCACHE) += sc-r5k.o
diff --git a/arch/mips/mm/c-octeon.c b/arch/mips/mm/c-octeon.c
new file mode 100644
index 0000000..44d01a0
--- /dev/null
+++ b/arch/mips/mm/c-octeon.c
@@ -0,0 +1,307 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2005-2007 Cavium Networks
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/bitops.h>
+#include <linux/cpu.h>
+#include <linux/io.h>
+
+#include <asm/bcache.h>
+#include <asm/bootinfo.h>
+#include <asm/cacheops.h>
+#include <asm/cpu-features.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/r4kcache.h>
+#include <asm/system.h>
+#include <asm/mmu_context.h>
+#include <asm/war.h>
+
+#include <asm/octeon/octeon.h>
+
+unsigned long long cache_err_dcache[NR_CPUS];
+
+/**
+ * Octeon automatically flushes the dcache on tlb changes, so
+ * from Linux's viewpoint it acts much like a physically
+ * tagged cache. No flushing is needed
+ *
+ */
+static void octeon_flush_data_cache_page(unsigned long addr)
+{
+ /* Nothing to do */
+}
+
+static inline void octeon_local_flush_icache(void)
+{
+ asm volatile ("synci 0($0)");
+}
+
+/*
+ * Flush local I-cache for the specified range.
+ */
+static void local_octeon_flush_icache_range(unsigned long start,
+ unsigned long end)
+{
+ octeon_local_flush_icache();
+}
+
+/**
+ * Flush caches as necessary for all cores affected by a
+ * vma. If no vma is supplied, all cores are flushed.
+ *
+ * @vma: VMA to flush or NULL to flush all icaches.
+ */
+static void octeon_flush_icache_all_cores(struct vm_area_struct *vma)
+{
+ extern void octeon_send_ipi_single(int cpu, unsigned int action);
+#ifdef CONFIG_SMP
+ int cpu;
+ cpumask_t mask;
+#endif
+
+ mb();
+ octeon_local_flush_icache();
+#ifdef CONFIG_SMP
+ preempt_disable();
+ cpu = smp_processor_id();
+
+ /*
+ * If we have a vma structure, we only need to worry about
+ * cores it has been used on
+ */
+ if (vma)
+ mask = vma->vm_mm->cpu_vm_mask;
+ else
+ mask = cpu_online_map;
+ cpu_clear(cpu, mask);
+ for_each_cpu_mask(cpu, mask)
+ octeon_send_ipi_single(cpu, SMP_ICACHE_FLUSH);
+
+ preempt_enable();
+#endif
+}
+
+
+/**
+ * Called to flush the icache on all cores
+ */
+static void octeon_flush_icache_all(void)
+{
+ octeon_flush_icache_all_cores(NULL);
+}
+
+
+/**
+ * Called to flush all memory associated with a memory
+ * context.
+ *
+ * @mm: Memory context to flush
+ */
+static void octeon_flush_cache_mm(struct mm_struct *mm)
+{
+ /*
+ * According to the R4K version of this file, CPUs without
+ * dcache aliases don't need to do anything here
+ */
+}
+
+
+/**
+ * Flush a range of kernel addresses out of the icache
+ *
+ */
+static void octeon_flush_icache_range(unsigned long start, unsigned long end)
+{
+ octeon_flush_icache_all_cores(NULL);
+}
+
+
+/**
+ * Flush the icache for a trampoline. These are used for interrupt
+ * and exception hooking.
+ *
+ * @addr: Address to flush
+ */
+static void octeon_flush_cache_sigtramp(unsigned long addr)
+{
+ struct vm_area_struct *vma;
+
+ vma = find_vma(current->mm, addr);
+ octeon_flush_icache_all_cores(vma);
+}
+
+
+/**
+ * Flush a range out of a vma
+ *
+ * @vma: VMA to flush
+ * @start:
+ * @end:
+ */
+static void octeon_flush_cache_range(struct vm_area_struct *vma,
+ unsigned long start, unsigned long end)
+{
+ if (vma->vm_flags & VM_EXEC)
+ octeon_flush_icache_all_cores(vma);
+}
+
+
+/**
+ * Flush a specific page of a vma
+ *
+ * @vma: VMA to flush page for
+ * @page: Page to flush
+ * @pfn:
+ */
+static void octeon_flush_cache_page(struct vm_area_struct *vma,
+ unsigned long page, unsigned long pfn)
+{
+ if (vma->vm_flags & VM_EXEC)
+ octeon_flush_icache_all_cores(vma);
+}
+
+
+/**
+ * Probe Octeon's caches
+ *
+ */
+static void __devinit probe_octeon(void)
+{
+ unsigned long icache_size;
+ unsigned long dcache_size;
+ unsigned int config1;
+ struct cpuinfo_mips *c = &current_cpu_data;
+
+ switch (c->cputype) {
+ case CPU_CAVIUM_OCTEON:
+ config1 = read_c0_config1();
+ c->icache.linesz = 2 << ((config1 >> 19) & 7);
+ c->icache.sets = 64 << ((config1 >> 22) & 7);
+ c->icache.ways = 1 + ((config1 >> 16) & 7);
+ c->icache.flags |= MIPS_CACHE_VTAG;
+ icache_size =
+ c->icache.sets * c->icache.ways * c->icache.linesz;
+ c->icache.waybit = ffs(icache_size / c->icache.ways) - 1;
+ c->dcache.linesz = 128;
+ if (OCTEON_IS_MODEL(OCTEON_CN3XXX))
+ c->dcache.sets = 1; /* CN3XXX has one Dcache set */
+ else
+ c->dcache.sets = 2; /* CN5XXX has two Dcache sets */
+ c->dcache.ways = 64;
+ dcache_size =
+ c->dcache.sets * c->dcache.ways * c->dcache.linesz;
+ c->dcache.waybit = ffs(dcache_size / c->dcache.ways) - 1;
+ c->options |= MIPS_CPU_PREFETCH;
+ break;
+
+ default:
+ panic("Unsupported Cavium Networks CPU type\n");
+ break;
+ }
+
+ /* compute a couple of other cache variables */
+ c->icache.waysize = icache_size / c->icache.ways;
+ c->dcache.waysize = dcache_size / c->dcache.ways;
+
+ c->icache.sets = icache_size / (c->icache.linesz * c->icache.ways);
+ c->dcache.sets = dcache_size / (c->dcache.linesz * c->dcache.ways);
+
+ if (smp_processor_id() == 0) {
+ pr_notice("Primary instruction cache %ldkB, %s, %d way, "
+ "%d sets, linesize %d bytes.\n",
+ icache_size >> 10,
+ cpu_has_vtag_icache ?
+ "virtually tagged" : "physically tagged",
+ c->icache.ways, c->icache.sets, c->icache.linesz);
+
+ pr_notice("Primary data cache %ldkB, %d-way, %d sets, "
+ "linesize %d bytes.\n",
+ dcache_size >> 10, c->dcache.ways,
+ c->dcache.sets, c->dcache.linesz);
+ }
+}
+
+
+/**
+ * Setup the Octeon cache flush routines
+ *
+ */
+void __devinit octeon_cache_init(void)
+{
+ extern unsigned long ebase;
+ extern char except_vec2_octeon;
+
+ memcpy((void *)(ebase + 0x100), &except_vec2_octeon, 0x80);
+ octeon_flush_cache_sigtramp(ebase + 0x100);
+
+ probe_octeon();
+
+ shm_align_mask = PAGE_SIZE - 1;
+
+ flush_cache_all = octeon_flush_icache_all;
+ __flush_cache_all = octeon_flush_icache_all;
+ flush_cache_mm = octeon_flush_cache_mm;
+ flush_cache_page = octeon_flush_cache_page;
+ flush_cache_range = octeon_flush_cache_range;
+ flush_cache_sigtramp = octeon_flush_cache_sigtramp;
+ flush_icache_all = octeon_flush_icache_all;
+ flush_data_cache_page = octeon_flush_data_cache_page;
+ flush_icache_range = octeon_flush_icache_range;
+ local_flush_icache_range = local_octeon_flush_icache_range;
+
+ build_clear_page();
+ build_copy_page();
+}
+
+/**
+ * Handle a cache error exception
+ */
+
+static void cache_parity_error_octeon(int non_recoverable)
+{
+ unsigned long coreid = cvmx_get_core_num();
+ uint64_t icache_err = read_octeon_c0_icacheerr();
+
+ pr_err("Cache error exception:\n");
+ pr_err("cp0_errorepc == %lx\n", read_c0_errorepc());
+ if (icache_err & 1) {
+ pr_err("CacheErr (Icache) == %llx\n",
+ (unsigned long long)icache_err);
+ write_octeon_c0_icacheerr(0);
+ }
+ if (cache_err_dcache[coreid] & 1) {
+ pr_err("CacheErr (Dcache) == %llx\n",
+ (unsigned long long)cache_err_dcache[coreid]);
+ cache_err_dcache[coreid] = 0;
+ }
+
+ if (non_recoverable)
+ panic("Can't handle cache error: nested exception");
+}
+
+/**
+ * Called when the the exception is not recoverable
+ */
+
+asmlinkage void cache_parity_error_octeon_recoverable(void)
+{
+ cache_parity_error_octeon(0);
+}
+
+/**
+ * Called when the the exception is recoverable
+ */
+
+asmlinkage void cache_parity_error_octeon_non_recoverable(void)
+{
+ cache_parity_error_octeon(1);
+}
+
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index 1eb7c71..98ad0a8 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -182,6 +182,12 @@ void __devinit cpu_cache_init(void)
tx39_cache_init();
}
+ if (cpu_has_octeon_cache) {
+ extern void __weak octeon_cache_init(void);
+
+ octeon_cache_init();
+ }
+
setup_protection_map();
}
diff --git a/arch/mips/mm/cex-oct.S b/arch/mips/mm/cex-oct.S
new file mode 100644
index 0000000..3db8553
--- /dev/null
+++ b/arch/mips/mm/cex-oct.S
@@ -0,0 +1,70 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2006 Cavium Networks
+ * Cache error handler
+ */
+
+#include <asm/asm.h>
+#include <asm/regdef.h>
+#include <asm/mipsregs.h>
+#include <asm/stackframe.h>
+
+/*
+ * Handle cache error. Indicate to the second level handler whether
+ * the exception is recoverable.
+ */
+ LEAF(except_vec2_octeon)
+
+ .set push
+ .set mips64r2
+ .set noreorder
+ .set noat
+
+
+ /* due to an errata we need to read the COP0 CacheErr (Dcache)
+ * before any cache/DRAM access */
+
+ rdhwr k0, $0 /* get core_id */
+ PTR_LA k1, cache_err_dcache
+ sll k0, k0, 3
+ PTR_ADDU k1, k0, k1 /* k1 = &cache_err_dcache[core_id] */
+
+ dmfc0 k0, CP0_CACHEERR, 1
+ sd k0, (k1)
+ dmtc0 $0, CP0_CACHEERR, 1
+
+ /* check whether this is a nested exception */
+ mfc0 k1, CP0_STATUS
+ andi k1, k1, ST0_EXL
+ beqz k1, 1f
+ nop
+ j cache_parity_error_octeon_non_recoverable
+ nop
+
+ /* exception is recoverable */
+1: j handle_cache_err
+ nop
+
+ .set pop
+ END(except_vec2_octeon)
+
+ /* We need to jump to handle_cache_err so that the previous handler
+ * can fit within 0x80 bytes. We also move from 0xFFFFFFFFAXXXXXXX
+ * space (uncached) to the 0xFFFFFFFF8XXXXXXX space (cached). */
+ LEAF(handle_cache_err)
+ .set push
+ .set noreorder
+ .set noat
+
+ SAVE_ALL
+ KMODE
+ jal cache_parity_error_octeon_recoverable
+ nop
+ j ret_from_exception
+ nop
+
+ .set pop
+ END(handle_cache_err)
diff --git a/arch/mips/mm/dma-default.c b/arch/mips/mm/dma-default.c
index e6708b3..546e697 100644
--- a/arch/mips/mm/dma-default.c
+++ b/arch/mips/mm/dma-default.c
@@ -111,7 +111,7 @@ EXPORT_SYMBOL(dma_alloc_coherent);
void dma_free_noncoherent(struct device *dev, size_t size, void *vaddr,
dma_addr_t dma_handle)
{
- plat_unmap_dma_mem(dma_handle);
+ plat_unmap_dma_mem(dev, dma_handle);
free_pages((unsigned long) vaddr, get_order(size));
}
@@ -122,7 +122,7 @@ void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
{
unsigned long addr = (unsigned long) vaddr;
- plat_unmap_dma_mem(dma_handle);
+ plat_unmap_dma_mem(dev, dma_handle);
if (!plat_device_is_coherent(dev))
addr = CAC_ADDR(addr);
@@ -173,7 +173,7 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
__dma_sync(dma_addr_to_virt(dma_addr), size,
direction);
- plat_unmap_dma_mem(dma_addr);
+ plat_unmap_dma_mem(dev, dma_addr);
}
EXPORT_SYMBOL(dma_unmap_single);
@@ -229,7 +229,7 @@ void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
dma_cache_wback_inv(addr, size);
}
- plat_unmap_dma_mem(dma_address);
+ plat_unmap_dma_mem(dev, dma_address);
}
EXPORT_SYMBOL(dma_unmap_page);
@@ -249,7 +249,7 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
if (addr)
__dma_sync(addr, sg->length, direction);
}
- plat_unmap_dma_mem(sg->dma_address);
+ plat_unmap_dma_mem(dev, sg->dma_address);
}
}
@@ -275,6 +275,7 @@ void dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle,
{
BUG_ON(direction == DMA_NONE);
+ plat_extra_sync_for_device(dev);
if (!plat_device_is_coherent(dev)) {
unsigned long addr;
@@ -305,6 +306,7 @@ void dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
{
BUG_ON(direction == DMA_NONE);
+ plat_extra_sync_for_device(dev);
if (!plat_device_is_coherent(dev)) {
unsigned long addr;
@@ -351,22 +353,14 @@ EXPORT_SYMBOL(dma_sync_sg_for_device);
int dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
{
- return 0;
+ return plat_dma_mapping_error(dev, dma_addr);
}
EXPORT_SYMBOL(dma_mapping_error);
int dma_supported(struct device *dev, u64 mask)
{
- /*
- * we fall back to GFP_DMA when the mask isn't all 1s,
- * so we can't guarantee allocations that must be
- * within a tighter range than GFP_DMA..
- */
- if (mask < DMA_BIT_MASK(24))
- return 0;
-
- return 1;
+ return plat_dma_supported(dev, mask);
}
EXPORT_SYMBOL(dma_supported);
@@ -383,6 +377,7 @@ void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
{
BUG_ON(direction == DMA_NONE);
+ plat_extra_sync_for_device(dev);
if (!plat_device_is_coherent(dev))
__dma_sync((unsigned long)vaddr, size, direction);
}
diff --git a/arch/mips/mm/tlb-r4k.c b/arch/mips/mm/tlb-r4k.c
index 5ce2fa7..9619f66 100644
--- a/arch/mips/mm/tlb-r4k.c
+++ b/arch/mips/mm/tlb-r4k.c
@@ -478,7 +478,10 @@ void __cpuinit tlb_init(void)
probe_tlb(config);
write_c0_pagemask(PM_DEFAULT_MASK);
write_c0_wired(0);
- write_c0_framemask(0);
+ if (current_cpu_type() == CPU_R10000 ||
+ current_cpu_type() == CPU_R12000 ||
+ current_cpu_type() == CPU_R14000)
+ write_c0_framemask(0);
temp_tlb_entry = current_cpu_data.tlbsize - 1;
/* From this point on the ARC firmware is dead. */
diff --git a/arch/mips/mm/tlbex.c b/arch/mips/mm/tlbex.c
index 979cf91..4294203 100644
--- a/arch/mips/mm/tlbex.c
+++ b/arch/mips/mm/tlbex.c
@@ -317,6 +317,7 @@ static void __cpuinit build_tlb_write_entry(u32 **p, struct uasm_label **l,
case CPU_BCM3302:
case CPU_BCM4710:
case CPU_LOONGSON2:
+ case CPU_CAVIUM_OCTEON:
if (m4kc_tlbp_war())
uasm_i_nop(p);
tlbw(p);
diff --git a/arch/mips/mti-malta/malta-smtc.c b/arch/mips/mti-malta/malta-smtc.c
index aabd727..5ba3188 100644
--- a/arch/mips/mti-malta/malta-smtc.c
+++ b/arch/mips/mti-malta/malta-smtc.c
@@ -116,7 +116,7 @@ struct plat_smp_ops msmtc_smp_ops = {
void plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
{
- cpumask_t tmask = *affinity;
+ cpumask_t tmask;
int cpu = 0;
void smtc_set_irq_affinity(unsigned int irq, cpumask_t aff);
@@ -139,11 +139,12 @@ void plat_set_irq_affinity(unsigned int irq, const struct cpumask *affinity)
* be made to forward to an offline "CPU".
*/
+ cpumask_copy(&tmask, affinity);
for_each_cpu(cpu, affinity) {
if ((cpu_data[cpu].vpe_id != 0) || !cpu_online(cpu))
cpu_clear(cpu, tmask);
}
- irq_desc[irq].affinity = tmask;
+ cpumask_copy(irq_desc[irq].affinity, &tmask);
if (cpus_empty(tmask))
/*
diff --git a/arch/mips/sgi-ip22/ip22-int.c b/arch/mips/sgi-ip22/ip22-int.c
index f8b18af..0ecd5fe 100644
--- a/arch/mips/sgi-ip22/ip22-int.c
+++ b/arch/mips/sgi-ip22/ip22-int.c
@@ -155,7 +155,7 @@ static void indy_buserror_irq(void)
int irq = SGI_BUSERR_IRQ;
irq_enter();
- kstat_this_cpu.irqs[irq]++;
+ kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
ip22_be_interrupt(irq);
irq_exit();
}
diff --git a/arch/mips/sgi-ip22/ip22-time.c b/arch/mips/sgi-ip22/ip22-time.c
index 3dcb27e..c8f7d23 100644
--- a/arch/mips/sgi-ip22/ip22-time.c
+++ b/arch/mips/sgi-ip22/ip22-time.c
@@ -122,7 +122,7 @@ void indy_8254timer_irq(void)
char c;
irq_enter();
- kstat_this_cpu.irqs[irq]++;
+ kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
printk(KERN_ALERT "Oops, got 8254 interrupt.\n");
ArcRead(0, &c, 1, &cnt);
ArcEnterInteractiveMode();
diff --git a/arch/mips/sibyte/bcm1480/smp.c b/arch/mips/sibyte/bcm1480/smp.c
index dddfda8..3146916 100644
--- a/arch/mips/sibyte/bcm1480/smp.c
+++ b/arch/mips/sibyte/bcm1480/smp.c
@@ -178,9 +178,10 @@ struct plat_smp_ops bcm1480_smp_ops = {
void bcm1480_mailbox_interrupt(void)
{
int cpu = smp_processor_id();
+ int irq = K_BCM1480_INT_MBOX_0_0;
unsigned int action;
- kstat_this_cpu.irqs[K_BCM1480_INT_MBOX_0_0]++;
+ kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
/* Load the mailbox register to figure out what we're supposed to do */
action = (__raw_readq(mailbox_0_regs[cpu]) >> 48) & 0xffff;
diff --git a/arch/mips/sibyte/sb1250/smp.c b/arch/mips/sibyte/sb1250/smp.c
index 5950a28..cad1400 100644
--- a/arch/mips/sibyte/sb1250/smp.c
+++ b/arch/mips/sibyte/sb1250/smp.c
@@ -166,9 +166,10 @@ struct plat_smp_ops sb_smp_ops = {
void sb1250_mailbox_interrupt(void)
{
int cpu = smp_processor_id();
+ int irq = K_INT_MBOX_0;
unsigned int action;
- kstat_this_cpu.irqs[K_INT_MBOX_0]++;
+ kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
/* Load the mailbox register to figure out what we're supposed to do */
action = (____raw_readq(mailbox_regs[cpu]) >> 48) & 0xffff;
diff --git a/arch/mn10300/kernel/mn10300-watchdog.c b/arch/mn10300/kernel/mn10300-watchdog.c
index 10811e9..2e370d8 100644
--- a/arch/mn10300/kernel/mn10300-watchdog.c
+++ b/arch/mn10300/kernel/mn10300-watchdog.c
@@ -130,6 +130,7 @@ void watchdog_interrupt(struct pt_regs *regs, enum exception_code excep)
* the stack NMI-atomically, it's safe to use smp_processor_id().
*/
int sum, cpu = smp_processor_id();
+ int irq = NMIIRQ;
u8 wdt, tmp;
wdt = WDCTR & ~WDCTR_WDCNE;
@@ -138,7 +139,7 @@ void watchdog_interrupt(struct pt_regs *regs, enum exception_code excep)
NMICR = NMICR_WDIF;
nmi_count(cpu)++;
- kstat_this_cpu.irqs[NMIIRQ]++;
+ kstat_incr_irqs_this_cpu(irq, irq_to_desc(irq));
sum = irq_stat[cpu].__irq_count;
if (last_irq_sums[cpu] == sum) {
diff --git a/arch/parisc/kernel/irq.c b/arch/parisc/kernel/irq.c
index ac2c822..4948280 100644
--- a/arch/parisc/kernel/irq.c
+++ b/arch/parisc/kernel/irq.c
@@ -120,7 +120,7 @@ int cpu_check_affinity(unsigned int irq, cpumask_t *dest)
if (CHECK_IRQ_PER_CPU(irq)) {
/* Bad linux design decision. The mask has already
* been set; we must reset it */
- irq_desc[irq].affinity = CPU_MASK_ALL;
+ cpumask_setall(irq_desc[irq].affinity);
return -EINVAL;
}
@@ -136,7 +136,7 @@ static void cpu_set_affinity_irq(unsigned int irq, const struct cpumask *dest)
if (cpu_check_affinity(irq, dest))
return;
- irq_desc[irq].affinity = *dest;
+ cpumask_copy(irq_desc[irq].affinity, dest);
}
#endif
@@ -295,7 +295,7 @@ int txn_alloc_irq(unsigned int bits_wide)
unsigned long txn_affinity_addr(unsigned int irq, int cpu)
{
#ifdef CONFIG_SMP
- irq_desc[irq].affinity = cpumask_of_cpu(cpu);
+ cpumask_copy(irq_desc[irq].affinity, cpumask_of(cpu));
#endif
return per_cpu(cpu_data, cpu).txn_addr;
@@ -352,7 +352,7 @@ void do_cpu_irq_mask(struct pt_regs *regs)
irq = eirr_to_irq(eirr_val);
#ifdef CONFIG_SMP
- dest = irq_desc[irq].affinity;
+ cpumask_copy(&dest, irq_desc[irq].affinity);
if (CHECK_IRQ_PER_CPU(irq_desc[irq].status) &&
!cpu_isset(smp_processor_id(), dest)) {
int cpu = first_cpu(dest);
diff --git a/arch/powerpc/boot/dts/gef_sbc610.dts b/arch/powerpc/boot/dts/gef_sbc610.dts
index 9708b34..e78c355 100644
--- a/arch/powerpc/boot/dts/gef_sbc610.dts
+++ b/arch/powerpc/boot/dts/gef_sbc610.dts
@@ -88,6 +88,21 @@
compatible = "gef,fpga-regs";
reg = <0x4 0x0 0x40>;
};
+
+ wdt@4,2000 {
+ compatible = "gef,fpga-wdt";
+ reg = <0x4 0x2000 0x8>;
+ interrupts = <0x1a 0x4>;
+ interrupt-parent = <&gef_pic>;
+ };
+ /* Second watchdog available, driver currently supports one.
+ wdt@4,2010 {
+ compatible = "gef,fpga-wdt";
+ reg = <0x4 0x2010 0x8>;
+ interrupts = <0x1b 0x4>;
+ interrupt-parent = <&gef_pic>;
+ };
+ */
gef_pic: pic@4,4000 {
#interrupt-cells = <1>;
interrupt-controller;
diff --git a/arch/powerpc/configs/86xx/gef_sbc610_defconfig b/arch/powerpc/configs/86xx/gef_sbc610_defconfig
index cd1ffa4..391874c 100644
--- a/arch/powerpc/configs/86xx/gef_sbc610_defconfig
+++ b/arch/powerpc/configs/86xx/gef_sbc610_defconfig
@@ -1164,6 +1164,7 @@ CONFIG_WATCHDOG=y
# CONFIG_SOFT_WATCHDOG is not set
# CONFIG_ALIM7101_WDT is not set
# CONFIG_8xxx_WDT is not set
+CONFIG_GEF_WDT=y
#
# PCI-based Watchdog Cards
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index f5ae487..7f8e6a9 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -241,7 +241,7 @@ void fixup_irqs(cpumask_t map)
if (irq_desc[irq].status & IRQ_PER_CPU)
continue;
- cpus_and(mask, irq_desc[irq].affinity, map);
+ cpumask_and(&mask, irq_desc[irq].affinity, &map);
if (any_online_cpu(mask) == NR_CPUS) {
printk("Breaking affinity for irq %i\n", irq);
mask = map;
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 47bf15c..04e8ece 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -182,6 +182,7 @@ SECTIONS
. = ALIGN(PAGE_SIZE);
.data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
__per_cpu_start = .;
+ *(.data.percpu.page_aligned)
*(.data.percpu)
*(.data.percpu.shared_aligned)
__per_cpu_end = .;
diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.c b/arch/powerpc/platforms/cell/cbe_cpufreq.c
index ec7c8f4..e6506cd 100644
--- a/arch/powerpc/platforms/cell/cbe_cpufreq.c
+++ b/arch/powerpc/platforms/cell/cbe_cpufreq.c
@@ -118,7 +118,7 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
policy->cur = cbe_freqs[cur_pmode].frequency;
#ifdef CONFIG_SMP
- policy->cpus = per_cpu(cpu_sibling_map, policy->cpu);
+ cpumask_copy(policy->cpus, &per_cpu(cpu_sibling_map, policy->cpu));
#endif
cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu);
diff --git a/arch/powerpc/platforms/cell/cpufreq_spudemand.c b/arch/powerpc/platforms/cell/cpufreq_spudemand.c
index a3c6c01..968c1c0 100644
--- a/arch/powerpc/platforms/cell/cpufreq_spudemand.c
+++ b/arch/powerpc/platforms/cell/cpufreq_spudemand.c
@@ -110,7 +110,7 @@ static int spu_gov_govern(struct cpufreq_policy *policy, unsigned int event)
}
/* initialize spu_gov_info for all affected cpus */
- for_each_cpu_mask(i, policy->cpus) {
+ for_each_cpu(i, policy->cpus) {
affected_info = &per_cpu(spu_gov_info, i);
affected_info->policy = policy;
}
@@ -127,7 +127,7 @@ static int spu_gov_govern(struct cpufreq_policy *policy, unsigned int event)
spu_gov_cancel_work(info);
/* clean spu_gov_info for all affected cpus */
- for_each_cpu_mask (i, policy->cpus) {
+ for_each_cpu (i, policy->cpus) {
info = &per_cpu(spu_gov_info, i);
info->policy = NULL;
}
diff --git a/arch/powerpc/platforms/pasemi/cpufreq.c b/arch/powerpc/platforms/pasemi/cpufreq.c
index 86db47c..be2527a 100644
--- a/arch/powerpc/platforms/pasemi/cpufreq.c
+++ b/arch/powerpc/platforms/pasemi/cpufreq.c
@@ -213,7 +213,7 @@ static int pas_cpufreq_cpu_init(struct cpufreq_policy *policy)
pr_debug("current astate is at %d\n",cur_astate);
policy->cur = pas_freqs[cur_astate].frequency;
- policy->cpus = cpu_online_map;
+ cpumask_copy(policy->cpus, &cpu_online_map);
ppc_proc_freq = policy->cur * 1000ul;
diff --git a/arch/powerpc/platforms/powermac/cpufreq_64.c b/arch/powerpc/platforms/powermac/cpufreq_64.c
index 4dfb4bc..beb3833 100644
--- a/arch/powerpc/platforms/powermac/cpufreq_64.c
+++ b/arch/powerpc/platforms/powermac/cpufreq_64.c
@@ -362,7 +362,7 @@ static int g5_cpufreq_cpu_init(struct cpufreq_policy *policy)
/* secondary CPUs are tied to the primary one by the
* cpufreq core if in the secondary policy we tell it that
* it actually must be one policy together with all others. */
- policy->cpus = cpu_online_map;
+ cpumask_copy(policy->cpus, &cpu_online_map);
cpufreq_frequency_table_get_attr(g5_cpu_freqs, policy->cpu);
return cpufreq_frequency_table_cpuinfo(policy,
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index 84e058f..80b5134 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -153,9 +153,10 @@ static int get_irq_server(unsigned int virq, unsigned int strict_check)
{
int server;
/* For the moment only implement delivery to all cpus or one cpu */
- cpumask_t cpumask = irq_desc[virq].affinity;
+ cpumask_t cpumask;
cpumask_t tmp = CPU_MASK_NONE;
+ cpumask_copy(&cpumask, irq_desc[virq].affinity);
if (!distribute_irqs)
return default_server;
@@ -869,7 +870,7 @@ void xics_migrate_irqs_away(void)
virq, cpu);
/* Reset affinity to all cpus */
- irq_desc[virq].affinity = CPU_MASK_ALL;
+ cpumask_setall(irq_desc[virq].affinity);
desc->chip->set_affinity(virq, cpu_all_mask);
unlock:
spin_unlock_irqrestore(&desc->lock, flags);
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 3e0d89d..0afd21f 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -566,9 +566,10 @@ static void __init mpic_scan_ht_pics(struct mpic *mpic)
#ifdef CONFIG_SMP
static int irq_choose_cpu(unsigned int virt_irq)
{
- cpumask_t mask = irq_desc[virt_irq].affinity;
+ cpumask_t mask;
int cpuid;
+ cpumask_copy(&mask, irq_desc[virt_irq].affinity);
if (cpus_equal(mask, CPU_MASK_ALL)) {
static int irq_rover;
static DEFINE_SPINLOCK(irq_rover_lock);
diff --git a/arch/sparc/configs/sparc32_defconfig b/arch/sparc/configs/sparc32_defconfig
index 2e3a149..09ab46e 100644
--- a/arch/sparc/configs/sparc32_defconfig
+++ b/arch/sparc/configs/sparc32_defconfig
@@ -1,15 +1,21 @@
#
# Automatically generated make config: don't edit
-# Linux kernel version: 2.6.25
-# Tue Apr 29 01:28:58 2008
+# Linux kernel version: 2.6.28
+# Thu Jan 8 16:45:44 2009
#
+# CONFIG_64BIT is not set
+CONFIG_SPARC=y
+CONFIG_SPARC32=y
+# CONFIG_SPARC64 is not set
+CONFIG_ARCH_DEFCONFIG="arch/sparc/configs/sparc32_defconfig"
+CONFIG_BITS=32
+CONFIG_AUDIT_ARCH=y
CONFIG_MMU=y
CONFIG_HIGHMEM=y
CONFIG_ZONE_DMA=y
CONFIG_GENERIC_ISA_DMA=y
CONFIG_ARCH_NO_VIRT_TO_BUS=y
CONFIG_OF=y
-CONFIG_HZ=100
CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
#
@@ -66,31 +72,30 @@ CONFIG_SIGNALFD=y
CONFIG_TIMERFD=y
CONFIG_EVENTFD=y
CONFIG_SHMEM=y
+CONFIG_AIO=y
CONFIG_VM_EVENT_COUNTERS=y
+CONFIG_PCI_QUIRKS=y
CONFIG_SLAB=y
# CONFIG_SLUB is not set
# CONFIG_SLOB is not set
# CONFIG_PROFILING is not set
-# CONFIG_MARKERS is not set
CONFIG_HAVE_OPROFILE=y
-# CONFIG_HAVE_KPROBES is not set
-# CONFIG_HAVE_KRETPROBES is not set
-CONFIG_PROC_PAGE_MONITOR=y
+CONFIG_HAVE_ARCH_TRACEHOOK=y
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
CONFIG_SLABINFO=y
CONFIG_RT_MUTEXES=y
-# CONFIG_TINY_SHMEM is not set
CONFIG_BASE_SMALL=0
CONFIG_MODULES=y
+# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
# CONFIG_MODVERSIONS is not set
# CONFIG_MODULE_SRCVERSION_ALL is not set
-CONFIG_KMOD=y
CONFIG_BLOCK=y
# CONFIG_LBD is not set
# CONFIG_BLK_DEV_IO_TRACE is not set
-# CONFIG_LSF is not set
# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_BLK_DEV_INTEGRITY is not set
#
# IO Schedulers
@@ -105,59 +110,73 @@ CONFIG_DEFAULT_CFQ=y
# CONFIG_DEFAULT_NOOP is not set
CONFIG_DEFAULT_IOSCHED="cfq"
CONFIG_CLASSIC_RCU=y
+# CONFIG_TREE_RCU is not set
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_PREEMPT_RCU_TRACE is not set
+# CONFIG_FREEZER is not set
#
-# General machine setup
+# Processor type and features
#
# CONFIG_SMP is not set
-CONFIG_SPARC=y
-CONFIG_SPARC32=y
-CONFIG_SBUS=y
-CONFIG_SBUSCHAR=y
-CONFIG_SERIAL_CONSOLE=y
-CONFIG_SUN_AUXIO=y
-CONFIG_SUN_IO=y
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+# CONFIG_SCHED_HRTICK is not set
CONFIG_RWSEM_GENERIC_SPINLOCK=y
CONFIG_GENERIC_FIND_NEXT_BIT=y
CONFIG_GENERIC_HWEIGHT=y
CONFIG_GENERIC_CALIBRATE_DELAY=y
CONFIG_ARCH_MAY_HAVE_PC_FDC=y
-# CONFIG_ARCH_HAS_ILOG2_U32 is not set
-# CONFIG_ARCH_HAS_ILOG2_U64 is not set
CONFIG_EMULATED_CMPXCHG=y
-CONFIG_SUN_PM=y
-# CONFIG_SUN4 is not set
-CONFIG_PCI=y
-CONFIG_PCI_SYSCALL=y
-# CONFIG_ARCH_SUPPORTS_MSI is not set
-CONFIG_PCI_LEGACY=y
-# CONFIG_PCI_DEBUG is not set
-# CONFIG_NO_DMA is not set
-CONFIG_SUN_OPENPROMFS=m
-# CONFIG_SPARC_LED is not set
-CONFIG_BINFMT_ELF=y
-CONFIG_BINFMT_MISC=m
CONFIG_SELECT_MEMORY_MODEL=y
CONFIG_FLATMEM_MANUAL=y
# CONFIG_DISCONTIGMEM_MANUAL is not set
# CONFIG_SPARSEMEM_MANUAL is not set
CONFIG_FLATMEM=y
CONFIG_FLAT_NODE_MEM_MAP=y
-# CONFIG_SPARSEMEM_STATIC is not set
-# CONFIG_SPARSEMEM_VMEMMAP_ENABLE is not set
+CONFIG_PAGEFLAGS_EXTENDED=y
CONFIG_SPLIT_PTLOCK_CPUS=4
-# CONFIG_RESOURCES_64BIT is not set
+# CONFIG_PHYS_ADDR_T_64BIT is not set
CONFIG_ZONE_DMA_FLAG=1
CONFIG_BOUNCE=y
+CONFIG_UNEVICTABLE_LRU=y
+CONFIG_SUN_PM=y
+# CONFIG_SPARC_LED is not set
+CONFIG_SERIAL_CONSOLE=y
#
-# Networking
+# Bus options (PCI etc.)
#
+CONFIG_SBUS=y
+CONFIG_SBUSCHAR=y
+CONFIG_PCI=y
+CONFIG_PCI_SYSCALL=y
+# CONFIG_ARCH_SUPPORTS_MSI is not set
+CONFIG_PCI_LEGACY=y
+# CONFIG_PCI_DEBUG is not set
+# CONFIG_PCI_STUB is not set
+# CONFIG_PCCARD is not set
+CONFIG_SUN_OPENPROMFS=m
+CONFIG_SPARC32_PCI=y
+
+#
+# Executable file formats
+#
+CONFIG_BINFMT_ELF=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_HAVE_AOUT is not set
+CONFIG_BINFMT_MISC=m
CONFIG_NET=y
#
# Networking options
#
+# CONFIG_NET_NS is not set
+CONFIG_COMPAT_NET_DEV_OPS=y
CONFIG_PACKET=y
# CONFIG_PACKET_MMAP is not set
CONFIG_UNIX=y
@@ -166,6 +185,7 @@ CONFIG_XFRM_USER=m
# CONFIG_XFRM_SUB_POLICY is not set
# CONFIG_XFRM_MIGRATE is not set
# CONFIG_XFRM_STATISTICS is not set
+CONFIG_XFRM_IPCOMP=y
CONFIG_NET_KEY=m
# CONFIG_NET_KEY_MIGRATE is not set
CONFIG_INET=y
@@ -221,6 +241,7 @@ CONFIG_IPV6_TUNNEL=m
# CONFIG_TIPC is not set
# CONFIG_ATM is not set
# CONFIG_BRIDGE is not set
+# CONFIG_NET_DSA is not set
# CONFIG_VLAN_8021Q is not set
# CONFIG_DECNET is not set
# CONFIG_LLC2 is not set
@@ -231,6 +252,7 @@ CONFIG_IPV6_TUNNEL=m
# CONFIG_ECONET is not set
# CONFIG_WAN_ROUTER is not set
# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
#
# Network testing
@@ -241,14 +263,14 @@ CONFIG_NET_PKTGEN=m
# CONFIG_IRDA is not set
# CONFIG_BT is not set
# CONFIG_AF_RXRPC is not set
-
-#
-# Wireless
-#
+# CONFIG_PHONET is not set
+CONFIG_WIRELESS=y
# CONFIG_CFG80211 is not set
+CONFIG_WIRELESS_OLD_REGULATORY=y
# CONFIG_WIRELESS_EXT is not set
+# CONFIG_LIB80211 is not set
# CONFIG_MAC80211 is not set
-# CONFIG_IEEE80211 is not set
+# CONFIG_WIMAX is not set
# CONFIG_RFKILL is not set
# CONFIG_NET_9P is not set
@@ -262,7 +284,9 @@ CONFIG_NET_PKTGEN=m
CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
CONFIG_STANDALONE=y
CONFIG_PREVENT_FIRMWARE_BUILD=y
-# CONFIG_FW_LOADER is not set
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
# CONFIG_DEBUG_DRIVER is not set
# CONFIG_DEBUG_DEVRES is not set
# CONFIG_SYS_HYPERVISOR is not set
@@ -286,12 +310,15 @@ CONFIG_BLK_DEV_RAM_SIZE=4096
# CONFIG_BLK_DEV_XIP is not set
# CONFIG_CDROM_PKTCDVD is not set
# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_HD is not set
CONFIG_MISC_DEVICES=y
# CONFIG_PHANTOM is not set
# CONFIG_EEPROM_93CX6 is not set
# CONFIG_SGI_IOC4 is not set
# CONFIG_TIFM_CORE is not set
# CONFIG_ENCLOSURE_SERVICES is not set
+# CONFIG_HP_ILO is not set
+# CONFIG_C2PORT is not set
CONFIG_HAVE_IDE=y
# CONFIG_IDE is not set
@@ -335,6 +362,7 @@ CONFIG_SCSI_SPI_ATTRS=y
# CONFIG_SCSI_SRP_ATTRS is not set
CONFIG_SCSI_LOWLEVEL=y
# CONFIG_ISCSI_TCP is not set
+# CONFIG_SCSI_CXGB3_ISCSI is not set
# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
# CONFIG_SCSI_3W_9XXX is not set
# CONFIG_SCSI_ACARD is not set
@@ -348,6 +376,8 @@ CONFIG_SCSI_LOWLEVEL=y
# CONFIG_MEGARAID_LEGACY is not set
# CONFIG_MEGARAID_SAS is not set
# CONFIG_SCSI_HPTIOP is not set
+# CONFIG_LIBFC is not set
+# CONFIG_FCOE is not set
# CONFIG_SCSI_DMX3191D is not set
# CONFIG_SCSI_FUTURE_DOMAIN is not set
# CONFIG_SCSI_IPS is not set
@@ -367,6 +397,7 @@ CONFIG_SCSI_QLOGICPTI=m
# CONFIG_SCSI_DEBUG is not set
CONFIG_SCSI_SUNESP=y
# CONFIG_SCSI_SRP is not set
+# CONFIG_SCSI_DH is not set
# CONFIG_ATA is not set
# CONFIG_MD is not set
# CONFIG_FUSION is not set
@@ -374,11 +405,14 @@ CONFIG_SCSI_SUNESP=y
#
# IEEE 1394 (FireWire) support
#
+
+#
+# Enable only one of the two stacks, unless you know what you are doing
+#
# CONFIG_FIREWIRE is not set
# CONFIG_IEEE1394 is not set
# CONFIG_I2O is not set
CONFIG_NETDEVICES=y
-# CONFIG_NETDEVICES_MULTIQUEUE is not set
CONFIG_DUMMY=m
# CONFIG_BONDING is not set
# CONFIG_MACVLAN is not set
@@ -402,14 +436,16 @@ CONFIG_SUNQE=m
# CONFIG_IBM_NEW_EMAC_RGMII is not set
# CONFIG_IBM_NEW_EMAC_TAH is not set
# CONFIG_IBM_NEW_EMAC_EMAC4 is not set
+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set
+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set
+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set
# CONFIG_NET_PCI is not set
# CONFIG_B44 is not set
+# CONFIG_ATL2 is not set
CONFIG_NETDEV_1000=y
# CONFIG_ACENIC is not set
# CONFIG_DL2K is not set
# CONFIG_E1000 is not set
-# CONFIG_E1000E is not set
-# CONFIG_E1000E_ENABLED is not set
# CONFIG_IP1000 is not set
# CONFIG_IGB is not set
# CONFIG_MYRI_SBUS is not set
@@ -425,18 +461,25 @@ CONFIG_NETDEV_1000=y
# CONFIG_BNX2 is not set
# CONFIG_QLA3XXX is not set
# CONFIG_ATL1 is not set
+# CONFIG_ATL1E is not set
+# CONFIG_JME is not set
CONFIG_NETDEV_10000=y
# CONFIG_CHELSIO_T1 is not set
+CONFIG_CHELSIO_T3_DEPENDS=y
# CONFIG_CHELSIO_T3 is not set
+# CONFIG_ENIC is not set
# CONFIG_IXGBE is not set
# CONFIG_IXGB is not set
# CONFIG_S2IO is not set
# CONFIG_MYRI10GE is not set
# CONFIG_NETXEN_NIC is not set
# CONFIG_NIU is not set
+# CONFIG_MLX4_EN is not set
# CONFIG_MLX4_CORE is not set
# CONFIG_TEHUTI is not set
# CONFIG_BNX2X is not set
+# CONFIG_QLGE is not set
+# CONFIG_SFC is not set
# CONFIG_TR is not set
#
@@ -445,6 +488,10 @@ CONFIG_NETDEV_10000=y
# CONFIG_WLAN_PRE80211 is not set
# CONFIG_WLAN_80211 is not set
# CONFIG_IWLWIFI_LEDS is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
# CONFIG_WAN is not set
# CONFIG_FDDI is not set
# CONFIG_HIPPI is not set
@@ -492,9 +539,11 @@ CONFIG_MOUSE_PS2_LOGIPS2PP=y
CONFIG_MOUSE_PS2_SYNAPTICS=y
CONFIG_MOUSE_PS2_LIFEBOOK=y
CONFIG_MOUSE_PS2_TRACKPOINT=y
+# CONFIG_MOUSE_PS2_ELANTECH is not set
# CONFIG_MOUSE_PS2_TOUCHKIT is not set
CONFIG_MOUSE_SERIAL=m
# CONFIG_MOUSE_APPLETOUCH is not set
+# CONFIG_MOUSE_BCM5974 is not set
# CONFIG_MOUSE_VSXXXAA is not set
# CONFIG_INPUT_JOYSTICK is not set
# CONFIG_INPUT_TABLET is not set
@@ -516,15 +565,18 @@ CONFIG_SERIO_LIBPS2=m
# Character devices
#
CONFIG_VT=y
+CONFIG_CONSOLE_TRANSLATIONS=y
CONFIG_VT_CONSOLE=y
CONFIG_HW_CONSOLE=y
# CONFIG_VT_HW_CONSOLE_BINDING is not set
+CONFIG_DEVKMEM=y
# CONFIG_SERIAL_NONSTANDARD is not set
# CONFIG_NOZOMI is not set
#
# Serial drivers
#
+# CONFIG_SERIAL_8250 is not set
#
# Non-8250 serial port support
@@ -540,23 +592,20 @@ CONFIG_SERIAL_CORE_CONSOLE=y
CONFIG_CONSOLE_POLL=y
# CONFIG_SERIAL_JSM is not set
CONFIG_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
CONFIG_LEGACY_PTYS=y
CONFIG_LEGACY_PTY_COUNT=256
# CONFIG_IPMI_HANDLER is not set
CONFIG_HW_RANDOM=m
-CONFIG_JS_RTC=m
# CONFIG_R3964 is not set
# CONFIG_APPLICOM is not set
# CONFIG_RAW_DRIVER is not set
# CONFIG_TCG_TPM is not set
CONFIG_DEVPORT=y
# CONFIG_I2C is not set
-
-#
-# SPI support
-#
# CONFIG_SPI is not set
-# CONFIG_SPI_MASTER is not set
+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y
+# CONFIG_GPIOLIB is not set
# CONFIG_W1 is not set
# CONFIG_POWER_SUPPLY is not set
CONFIG_HWMON=y
@@ -577,25 +626,38 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_W83627EHF is not set
# CONFIG_HWMON_DEBUG_CHIP is not set
# CONFIG_THERMAL is not set
+# CONFIG_THERMAL_HWMON is not set
# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
#
# Sonics Silicon Backplane
#
-CONFIG_SSB_POSSIBLE=y
# CONFIG_SSB is not set
#
# Multifunction device drivers
#
+# CONFIG_MFD_CORE is not set
# CONFIG_MFD_SM501 is not set
# CONFIG_HTC_PASIC3 is not set
+# CONFIG_MFD_TMIO is not set
+# CONFIG_REGULATOR is not set
#
# Multimedia devices
#
+
+#
+# Multimedia core support
+#
# CONFIG_VIDEO_DEV is not set
# CONFIG_DVB_CORE is not set
+# CONFIG_VIDEO_MEDIA is not set
+
+#
+# Multimedia drivers
+#
# CONFIG_DAB is not set
#
@@ -616,15 +678,17 @@ CONFIG_SSB_POSSIBLE=y
#
# CONFIG_PROM_CONSOLE is not set
CONFIG_DUMMY_CONSOLE=y
-
-#
-# Sound
-#
# CONFIG_SOUND is not set
CONFIG_HID_SUPPORT=y
CONFIG_HID=y
# CONFIG_HID_DEBUG is not set
# CONFIG_HIDRAW is not set
+# CONFIG_HID_PID is not set
+
+#
+# Special HID drivers
+#
+CONFIG_HID_COMPAT=y
CONFIG_USB_SUPPORT=y
CONFIG_USB_ARCH_HAS_HCD=y
CONFIG_USB_ARCH_HAS_OHCI=y
@@ -632,32 +696,71 @@ CONFIG_USB_ARCH_HAS_EHCI=y
# CONFIG_USB is not set
#
-# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
+# Enable Host or Gadget support to see Inventra options
+#
+
+#
+# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
#
# CONFIG_USB_GADGET is not set
+
+#
+# OTG and related infrastructure
+#
+# CONFIG_UWB is not set
# CONFIG_MMC is not set
# CONFIG_MEMSTICK is not set
# CONFIG_NEW_LEDS is not set
+# CONFIG_ACCESSIBILITY is not set
# CONFIG_INFINIBAND is not set
-# CONFIG_RTC_CLASS is not set
+CONFIG_RTC_LIB=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_HCTOSYS=y
+CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
+# CONFIG_RTC_DEBUG is not set
+
+#
+# RTC interfaces
+#
+CONFIG_RTC_INTF_SYSFS=y
+CONFIG_RTC_INTF_PROC=y
+CONFIG_RTC_INTF_DEV=y
+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
+# CONFIG_RTC_DRV_TEST is not set
+
+#
+# SPI RTC drivers
+#
+
+#
+# Platform RTC drivers
+#
+# CONFIG_RTC_DRV_DS1286 is not set
+# CONFIG_RTC_DRV_DS1511 is not set
+# CONFIG_RTC_DRV_DS1553 is not set
+# CONFIG_RTC_DRV_DS1742 is not set
+# CONFIG_RTC_DRV_STK17TA8 is not set
+# CONFIG_RTC_DRV_M48T86 is not set
+# CONFIG_RTC_DRV_M48T35 is not set
+CONFIG_RTC_DRV_M48T59=y
+# CONFIG_RTC_DRV_BQ4802 is not set
+# CONFIG_RTC_DRV_V3020 is not set
+
+#
+# on-CPU RTC drivers
+#
+# CONFIG_DMADEVICES is not set
# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
#
# Misc Linux/SPARC drivers
#
CONFIG_SUN_OPENPROMIO=m
-CONFIG_SUN_MOSTEK_RTC=m
-# CONFIG_SUN_BPP is not set
-# CONFIG_SUN_VIDEOPIX is not set
# CONFIG_TADPOLE_TS102_UCTRL is not set
# CONFIG_SUN_JSFLASH is not set
#
-# Unix98 PTY support
-#
-CONFIG_UNIX98_PTY_COUNT=256
-
-#
# File systems
#
CONFIG_EXT2_FS=y
@@ -666,11 +769,12 @@ 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_EXT4DEV_FS is not set
+# CONFIG_EXT4_FS 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_FILE_LOCKING=y
# CONFIG_XFS_FS is not set
# CONFIG_OCFS2_FS is not set
CONFIG_DNOTIFY=y
@@ -702,14 +806,12 @@ CONFIG_ISO9660_FS=m
CONFIG_PROC_FS=y
CONFIG_PROC_KCORE=y
CONFIG_PROC_SYSCTL=y
+CONFIG_PROC_PAGE_MONITOR=y
CONFIG_SYSFS=y
# CONFIG_TMPFS is not set
# CONFIG_HUGETLB_PAGE is not set
# CONFIG_CONFIGFS_FS is not set
-
-#
-# Miscellaneous filesystems
-#
+CONFIG_MISC_FILESYSTEMS=y
# CONFIG_ADFS_FS is not set
# CONFIG_AFFS_FS is not set
# CONFIG_HFS_FS is not set
@@ -720,6 +822,7 @@ CONFIG_SYSFS=y
# CONFIG_CRAMFS is not set
# CONFIG_VXFS_FS is not set
# CONFIG_MINIX_FS is not set
+# CONFIG_OMFS_FS is not set
# CONFIG_HPFS_FS is not set
# CONFIG_QNX4FS_FS is not set
CONFIG_ROMFS_FS=m
@@ -729,13 +832,13 @@ CONFIG_NETWORK_FILESYSTEMS=y
CONFIG_NFS_FS=y
# CONFIG_NFS_V3 is not set
# CONFIG_NFS_V4 is not set
-# CONFIG_NFSD is not set
CONFIG_ROOT_NFS=y
+# CONFIG_NFSD is not set
CONFIG_LOCKD=y
CONFIG_NFS_COMMON=y
CONFIG_SUNRPC=y
CONFIG_SUNRPC_GSS=m
-# CONFIG_SUNRPC_BIND34 is not set
+# CONFIG_SUNRPC_REGISTER_V4 is not set
CONFIG_RPCSEC_GSS_KRB5=m
# CONFIG_RPCSEC_GSS_SPKM3 is not set
# CONFIG_SMB_FS is not set
@@ -806,9 +909,12 @@ CONFIG_MAGIC_SYSRQ=y
# CONFIG_HEADERS_CHECK is not set
CONFIG_DEBUG_KERNEL=y
CONFIG_DETECT_SOFTLOCKUP=y
+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
# CONFIG_SCHED_DEBUG is not set
# CONFIG_SCHEDSTATS is not set
# CONFIG_TIMER_STATS is not set
+# CONFIG_DEBUG_OBJECTS is not set
# CONFIG_DEBUG_SLAB is not set
# CONFIG_DEBUG_RT_MUTEXES is not set
# CONFIG_RT_MUTEX_TESTER is not set
@@ -822,37 +928,59 @@ CONFIG_DEBUG_BUGVERBOSE=y
# CONFIG_DEBUG_INFO is not set
# CONFIG_DEBUG_VM is not set
# CONFIG_DEBUG_WRITECOUNT is not set
+CONFIG_DEBUG_MEMORY_INIT=y
# CONFIG_DEBUG_LIST is not set
# CONFIG_DEBUG_SG is not set
-CONFIG_FRAME_POINTER=y
+# CONFIG_DEBUG_NOTIFIERS is not set
# CONFIG_BOOT_PRINTK_DELAY is not set
# CONFIG_RCU_TORTURE_TEST is not set
+# CONFIG_RCU_CPU_STALL_DETECTOR is not set
# CONFIG_BACKTRACE_SELF_TEST is not set
+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
# CONFIG_FAULT_INJECTION is not set
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+
+#
+# Tracers
+#
+# CONFIG_SCHED_TRACER is not set
+# CONFIG_CONTEXT_SWITCH_TRACER is not set
+# CONFIG_BOOT_TRACER is not set
+# CONFIG_TRACE_BRANCH_PROFILING is not set
+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
# CONFIG_SAMPLES is not set
-CONFIG_KGDB=y
CONFIG_HAVE_ARCH_KGDB=y
+CONFIG_KGDB=y
CONFIG_KGDB_SERIAL_CONSOLE=y
CONFIG_KGDB_TESTS=y
# CONFIG_KGDB_TESTS_ON_BOOT is not set
# CONFIG_DEBUG_STACK_USAGE is not set
+# CONFIG_STACK_DEBUG is not set
#
# Security options
#
# CONFIG_KEYS is not set
# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
# CONFIG_SECURITY_FILE_CAPABILITIES is not set
CONFIG_CRYPTO=y
#
# Crypto core or helper
#
+# CONFIG_CRYPTO_FIPS is not set
CONFIG_CRYPTO_ALGAPI=y
+CONFIG_CRYPTO_ALGAPI2=y
CONFIG_CRYPTO_AEAD=y
+CONFIG_CRYPTO_AEAD2=y
CONFIG_CRYPTO_BLKCIPHER=y
+CONFIG_CRYPTO_BLKCIPHER2=y
CONFIG_CRYPTO_HASH=y
+CONFIG_CRYPTO_HASH2=y
+CONFIG_CRYPTO_RNG2=y
CONFIG_CRYPTO_MANAGER=y
+CONFIG_CRYPTO_MANAGER2=y
# CONFIG_CRYPTO_GF128MUL is not set
CONFIG_CRYPTO_NULL=m
# CONFIG_CRYPTO_CRYPTD is not set
@@ -890,6 +1018,10 @@ CONFIG_CRYPTO_CRC32C=m
CONFIG_CRYPTO_MD4=y
CONFIG_CRYPTO_MD5=y
CONFIG_CRYPTO_MICHAEL_MIC=m
+# CONFIG_CRYPTO_RMD128 is not set
+# CONFIG_CRYPTO_RMD160 is not set
+# CONFIG_CRYPTO_RMD256 is not set
+# CONFIG_CRYPTO_RMD320 is not set
CONFIG_CRYPTO_SHA1=y
CONFIG_CRYPTO_SHA256=m
CONFIG_CRYPTO_SHA512=m
@@ -921,15 +1053,21 @@ CONFIG_CRYPTO_TWOFISH_COMMON=m
#
CONFIG_CRYPTO_DEFLATE=y
# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRYPTO_HW is not set
#
# Library routines
#
CONFIG_BITREVERSE=y
-# CONFIG_GENERIC_FIND_FIRST_BIT is not set
+CONFIG_GENERIC_FIND_LAST_BIT=y
# CONFIG_CRC_CCITT is not set
# CONFIG_CRC16 is not set
+# CONFIG_CRC_T10DIF is not set
# CONFIG_CRC_ITU_T is not set
CONFIG_CRC32=y
# CONFIG_CRC7 is not set
diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h
index 73d4552..33e31ce 100644
--- a/arch/sparc/include/asm/oplib_32.h
+++ b/arch/sparc/include/asm/oplib_32.h
@@ -177,17 +177,6 @@ extern void prom_putsegment(int context, unsigned long virt_addr,
/* PROM device tree traversal functions... */
-#ifdef PROMLIB_INTERNAL
-
-/* Internal version of prom_getchild. */
-extern int __prom_getchild(int parent_node);
-
-/* Internal version of prom_getsibling. */
-extern int __prom_getsibling(int node);
-
-#endif
-
-
/* Get the child node of the given node, or zero if no child exists. */
extern int prom_getchild(int parent_node);
diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h
index 6d2c2ca..a5db031 100644
--- a/arch/sparc/include/asm/oplib_64.h
+++ b/arch/sparc/include/asm/oplib_64.h
@@ -218,16 +218,6 @@ extern void prom_unmap(unsigned long size, unsigned long vaddr);
/* PROM device tree traversal functions... */
-#ifdef PROMLIB_INTERNAL
-
-/* Internal version of prom_getchild. */
-extern int __prom_getchild(int parent_node);
-
-/* Internal version of prom_getsibling. */
-extern int __prom_getsibling(int node);
-
-#endif
-
/* Get the child node of the given node, or zero if no child exists. */
extern int prom_getchild(int parent_node);
diff --git a/arch/sparc/include/asm/signal.h b/arch/sparc/include/asm/signal.h
index 41535e7..cba4520 100644
--- a/arch/sparc/include/asm/signal.h
+++ b/arch/sparc/include/asm/signal.h
@@ -84,7 +84,11 @@
#define __OLD_NSIG 32
#define __NEW_NSIG 64
+#ifdef __arch64__
#define _NSIG_BPW 64
+#else
+#define _NSIG_BPW 32
+#endif
#define _NSIG_WORDS (__NEW_NSIG / _NSIG_BPW)
#define SIGRTMIN 32
diff --git a/arch/sparc/include/asm/topology_64.h b/arch/sparc/include/asm/topology_64.h
index b8a65b6..5bc0b8f 100644
--- a/arch/sparc/include/asm/topology_64.h
+++ b/arch/sparc/include/asm/topology_64.h
@@ -47,6 +47,10 @@ static inline int pcibus_to_node(struct pci_bus *pbus)
(pcibus_to_node(bus) == -1 ? \
CPU_MASK_ALL : \
node_to_cpumask(pcibus_to_node(bus)))
+#define cpumask_of_pcibus(bus) \
+ (pcibus_to_node(bus) == -1 ? \
+ CPU_MASK_ALL_PTR : \
+ cpumask_of_node(pcibus_to_node(bus)))
#define SD_NODE_INIT (struct sched_domain) { \
.min_interval = 8, \
diff --git a/arch/sparc/kernel/auxio_32.c b/arch/sparc/kernel/auxio_32.c
index 09c8572..45c4123 100644
--- a/arch/sparc/kernel/auxio_32.c
+++ b/arch/sparc/kernel/auxio_32.c
@@ -76,6 +76,7 @@ unsigned char get_auxio(void)
return sbus_readb(auxio_register);
return 0;
}
+EXPORT_SYMBOL(get_auxio);
void set_auxio(unsigned char bits_on, unsigned char bits_off)
{
@@ -102,7 +103,7 @@ void set_auxio(unsigned char bits_on, unsigned char bits_off)
};
spin_unlock_irqrestore(&auxio_lock, flags);
}
-
+EXPORT_SYMBOL(set_auxio);
/* sun4m power control register (AUXIO2) */
diff --git a/arch/sparc/kernel/auxio_64.c b/arch/sparc/kernel/auxio_64.c
index 8b67347..9f52db2 100644
--- a/arch/sparc/kernel/auxio_64.c
+++ b/arch/sparc/kernel/auxio_64.c
@@ -72,6 +72,7 @@ void auxio_set_led(int on)
bit = (ebus ? AUXIO_PCIO_LED : AUXIO_AUX1_LED);
__auxio_set_bit(bit, on, ebus);
}
+EXPORT_SYMBOL(auxio_set_led);
static void __auxio_sbus_set_lte(int on)
{
@@ -90,6 +91,7 @@ void auxio_set_lte(int on)
break;
}
}
+EXPORT_SYMBOL(auxio_set_lte);
static struct of_device_id __initdata auxio_match[] = {
{
diff --git a/arch/sparc/kernel/cpu.c b/arch/sparc/kernel/cpu.c
index 6c2da24..f0b8255 100644
--- a/arch/sparc/kernel/cpu.c
+++ b/arch/sparc/kernel/cpu.c
@@ -5,6 +5,7 @@
*/
#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/threads.h>
@@ -20,6 +21,7 @@
#include "kernel.h"
DEFINE_PER_CPU(cpuinfo_sparc, __cpu_data) = { 0 };
+EXPORT_PER_CPU_SYMBOL(__cpu_data);
struct cpu_info {
int psr_vers;
diff --git a/arch/sparc/kernel/idprom.c b/arch/sparc/kernel/idprom.c
index c16135e..57922f6 100644
--- a/arch/sparc/kernel/idprom.c
+++ b/arch/sparc/kernel/idprom.c
@@ -8,11 +8,14 @@
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
+#include <linux/module.h>
#include <asm/oplib.h>
#include <asm/idprom.h>
struct idprom *idprom;
+EXPORT_SYMBOL(idprom);
+
static struct idprom idprom_buffer;
#ifdef CONFIG_SPARC32
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 7ce14f0..87ea0d0 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -120,6 +120,7 @@ void __iomem *ioremap(unsigned long offset, unsigned long size)
sprintf(name, "phys_%08x", (u32)offset);
return _sparc_alloc_io(0, offset, size, name);
}
+EXPORT_SYMBOL(ioremap);
/*
* Comlimentary to ioremap().
@@ -141,6 +142,7 @@ void iounmap(volatile void __iomem *virtual)
kfree(res);
}
}
+EXPORT_SYMBOL(iounmap);
void __iomem *of_ioremap(struct resource *res, unsigned long offset,
unsigned long size, char *name)
@@ -237,6 +239,7 @@ void sbus_set_sbus64(struct device *dev, int x)
{
printk("sbus_set_sbus64: unsupported\n");
}
+EXPORT_SYMBOL(sbus_set_sbus64);
/*
* Allocate a chunk of memory suitable for DMA.
@@ -436,6 +439,7 @@ void *pci_alloc_consistent(struct pci_dev *pdev, size_t len, dma_addr_t *pba)
*pba = virt_to_phys(va); /* equals virt_to_bus (R.I.P.) for us. */
return (void *) res->start;
}
+EXPORT_SYMBOL(pci_alloc_consistent);
/* Free and unmap a consistent DMA buffer.
* cpu_addr is what was returned from pci_alloc_consistent,
@@ -477,6 +481,7 @@ void pci_free_consistent(struct pci_dev *pdev, size_t n, void *p, dma_addr_t ba)
free_pages(pgp, get_order(n));
}
+EXPORT_SYMBOL(pci_free_consistent);
/* Map a single buffer of the indicated size for DMA in streaming mode.
* The 32-bit bus address to use is returned.
@@ -491,6 +496,7 @@ dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size,
/* IIep is write-through, not flushing. */
return virt_to_phys(ptr);
}
+EXPORT_SYMBOL(pci_map_single);
/* Unmap a single streaming mode DMA translation. The dma_addr and size
* must match what was provided for in a previous pci_map_single call. All
@@ -508,6 +514,7 @@ void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t ba, size_t size,
(size + PAGE_SIZE-1) & PAGE_MASK);
}
}
+EXPORT_SYMBOL(pci_unmap_single);
/*
* Same as pci_map_single, but with pages.
@@ -519,6 +526,7 @@ dma_addr_t pci_map_page(struct pci_dev *hwdev, struct page *page,
/* IIep is write-through, not flushing. */
return page_to_phys(page) + offset;
}
+EXPORT_SYMBOL(pci_map_page);
void pci_unmap_page(struct pci_dev *hwdev,
dma_addr_t dma_address, size_t size, int direction)
@@ -526,6 +534,7 @@ void pci_unmap_page(struct pci_dev *hwdev,
BUG_ON(direction == PCI_DMA_NONE);
/* mmu_inval_dma_area XXX */
}
+EXPORT_SYMBOL(pci_unmap_page);
/* Map a set of buffers described by scatterlist in streaming
* mode for DMA. This is the scather-gather version of the
@@ -557,6 +566,7 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
}
return nents;
}
+EXPORT_SYMBOL(pci_map_sg);
/* Unmap a set of streaming mode DMA translations.
* Again, cpu read rules concerning calls here are the same as for
@@ -578,6 +588,7 @@ void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
}
}
}
+EXPORT_SYMBOL(pci_unmap_sg);
/* Make physical memory consistent for a single
* streaming mode DMA translation before or after a transfer.
@@ -597,6 +608,7 @@ void pci_dma_sync_single_for_cpu(struct pci_dev *hwdev, dma_addr_t ba, size_t si
(size + PAGE_SIZE-1) & PAGE_MASK);
}
}
+EXPORT_SYMBOL(pci_dma_sync_single_for_cpu);
void pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t ba, size_t size, int direction)
{
@@ -606,6 +618,7 @@ void pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t ba, size_t
(size + PAGE_SIZE-1) & PAGE_MASK);
}
}
+EXPORT_SYMBOL(pci_dma_sync_single_for_device);
/* Make physical memory consistent for a set of streaming
* mode DMA translations after a transfer.
@@ -628,6 +641,7 @@ void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sgl, int
}
}
}
+EXPORT_SYMBOL(pci_dma_sync_sg_for_cpu);
void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, int direction)
{
@@ -644,6 +658,7 @@ void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sgl,
}
}
}
+EXPORT_SYMBOL(pci_dma_sync_sg_for_device);
#endif /* CONFIG_PCI */
#ifdef CONFIG_PROC_FS
diff --git a/arch/sparc/kernel/irq_32.c b/arch/sparc/kernel/irq_32.c
index 1eff942..44dd5ee 100644
--- a/arch/sparc/kernel/irq_32.c
+++ b/arch/sparc/kernel/irq_32.c
@@ -294,6 +294,7 @@ void synchronize_irq(unsigned int irq)
while (sparc_irq[cpu_irq].flags & SPARC_IRQ_INPROGRESS)
cpu_relax();
}
+EXPORT_SYMBOL(synchronize_irq);
#endif /* SMP */
void unexpected_irq(int irq, void *dev_id, struct pt_regs * regs)
diff --git a/arch/sparc/kernel/irq_64.c b/arch/sparc/kernel/irq_64.c
index cab8e02..4ac5c65 100644
--- a/arch/sparc/kernel/irq_64.c
+++ b/arch/sparc/kernel/irq_64.c
@@ -247,9 +247,10 @@ struct irq_handler_data {
#ifdef CONFIG_SMP
static int irq_choose_cpu(unsigned int virt_irq)
{
- cpumask_t mask = irq_desc[virt_irq].affinity;
+ cpumask_t mask;
int cpuid;
+ cpumask_copy(&mask, irq_desc[virt_irq].affinity);
if (cpus_equal(mask, CPU_MASK_ALL)) {
static int irq_rover;
static DEFINE_SPINLOCK(irq_rover_lock);
@@ -854,7 +855,7 @@ void fixup_irqs(void)
!(irq_desc[irq].status & IRQ_PER_CPU)) {
if (irq_desc[irq].chip->set_affinity)
irq_desc[irq].chip->set_affinity(irq,
- &irq_desc[irq].affinity);
+ irq_desc[irq].affinity);
}
spin_unlock_irqrestore(&irq_desc[irq].lock, flags);
}
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index 923e9bb..4638fba 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -1077,6 +1077,7 @@ int pci_dma_supported(struct pci_dev *pdev, u64 device_mask)
return (device_mask & dma_addr_mask) == dma_addr_mask;
}
+EXPORT_SYMBOL(pci_dma_supported);
void pci_resource_to_user(const struct pci_dev *pdev, int bar,
const struct resource *rp, resource_size_t *start,
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index 75ed98b..85e7037 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -956,6 +956,7 @@ void outsb(unsigned long addr, const void *src, unsigned long count)
/* addr += 1; */
}
}
+EXPORT_SYMBOL(outsb);
void outsw(unsigned long addr, const void *src, unsigned long count)
{
@@ -966,6 +967,7 @@ void outsw(unsigned long addr, const void *src, unsigned long count)
/* addr += 2; */
}
}
+EXPORT_SYMBOL(outsw);
void outsl(unsigned long addr, const void *src, unsigned long count)
{
@@ -976,6 +978,7 @@ void outsl(unsigned long addr, const void *src, unsigned long count)
/* addr += 4; */
}
}
+EXPORT_SYMBOL(outsl);
void insb(unsigned long addr, void *dst, unsigned long count)
{
@@ -986,6 +989,7 @@ void insb(unsigned long addr, void *dst, unsigned long count)
/* addr += 1; */
}
}
+EXPORT_SYMBOL(insb);
void insw(unsigned long addr, void *dst, unsigned long count)
{
@@ -996,6 +1000,7 @@ void insw(unsigned long addr, void *dst, unsigned long count)
/* addr += 2; */
}
}
+EXPORT_SYMBOL(insw);
void insl(unsigned long addr, void *dst, unsigned long count)
{
@@ -1009,5 +1014,6 @@ void insl(unsigned long addr, void *dst, unsigned long count)
/* addr += 4; */
}
}
+EXPORT_SYMBOL(insl);
subsys_initcall(pcic_init);
diff --git a/arch/sparc/kernel/process_32.c b/arch/sparc/kernel/process_32.c
index 5a8d8ce..f4bee35 100644
--- a/arch/sparc/kernel/process_32.c
+++ b/arch/sparc/kernel/process_32.c
@@ -44,6 +44,7 @@
* Set in pm platform drivers (apc.c and pmc.c)
*/
void (*pm_idle)(void);
+EXPORT_SYMBOL(pm_idle);
/*
* Power-off handler instantiation for pm.h compliance
@@ -673,6 +674,7 @@ pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
"g1", "g2", "g3", "o0", "o1", "memory", "cc");
return retval;
}
+EXPORT_SYMBOL(kernel_thread);
unsigned long get_wchan(struct task_struct *task)
{
diff --git a/arch/sparc/kernel/process_64.c b/arch/sparc/kernel/process_64.c
index d5e2ace..cc8b560 100644
--- a/arch/sparc/kernel/process_64.c
+++ b/arch/sparc/kernel/process_64.c
@@ -678,6 +678,7 @@ pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
"g1", "g2", "g3", "o0", "o1", "memory", "cc");
return retval;
}
+EXPORT_SYMBOL(kernel_thread);
typedef struct {
union {
@@ -743,6 +744,7 @@ int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs)
}
return 1;
}
+EXPORT_SYMBOL(dump_fpu);
/*
* sparc_execve() executes a new program after the asm stub has set
diff --git a/arch/sparc/kernel/psycho_common.c b/arch/sparc/kernel/psycho_common.c
index 40689ae..8f1478475 100644
--- a/arch/sparc/kernel/psycho_common.c
+++ b/arch/sparc/kernel/psycho_common.c
@@ -11,19 +11,19 @@
#include "iommu_common.h"
#include "psycho_common.h"
-#define PSYCHO_STRBUF_CTRL_DENAB 0x0000000000000002UL
-#define PSYCHO_STCERR_WRITE 0x0000000000000002UL
-#define PSYCHO_STCERR_READ 0x0000000000000001UL
-#define PSYCHO_STCTAG_PPN 0x0fffffff00000000UL
-#define PSYCHO_STCTAG_VPN 0x00000000ffffe000UL
-#define PSYCHO_STCTAG_VALID 0x0000000000000002UL
-#define PSYCHO_STCTAG_WRITE 0x0000000000000001UL
-#define PSYCHO_STCLINE_LINDX 0x0000000001e00000UL
-#define PSYCHO_STCLINE_SPTR 0x00000000001f8000UL
-#define PSYCHO_STCLINE_LADDR 0x0000000000007f00UL
-#define PSYCHO_STCLINE_EPTR 0x00000000000000fcUL
-#define PSYCHO_STCLINE_VALID 0x0000000000000002UL
-#define PSYCHO_STCLINE_FOFN 0x0000000000000001UL
+#define PSYCHO_STRBUF_CTRL_DENAB 0x0000000000000002ULL
+#define PSYCHO_STCERR_WRITE 0x0000000000000002ULL
+#define PSYCHO_STCERR_READ 0x0000000000000001ULL
+#define PSYCHO_STCTAG_PPN 0x0fffffff00000000ULL
+#define PSYCHO_STCTAG_VPN 0x00000000ffffe000ULL
+#define PSYCHO_STCTAG_VALID 0x0000000000000002ULL
+#define PSYCHO_STCTAG_WRITE 0x0000000000000001ULL
+#define PSYCHO_STCLINE_LINDX 0x0000000001e00000ULL
+#define PSYCHO_STCLINE_SPTR 0x00000000001f8000ULL
+#define PSYCHO_STCLINE_LADDR 0x0000000000007f00ULL
+#define PSYCHO_STCLINE_EPTR 0x00000000000000fcULL
+#define PSYCHO_STCLINE_VALID 0x0000000000000002ULL
+#define PSYCHO_STCLINE_FOFN 0x0000000000000001ULL
static DEFINE_SPINLOCK(stc_buf_lock);
static unsigned long stc_error_buf[128];
@@ -144,10 +144,10 @@ static void psycho_record_iommu_tags_and_data(struct pci_pbm_info *pbm,
#define PSYCHO_IOMMU_TAG_WRITE (0x1UL << 21UL)
#define PSYCHO_IOMMU_TAG_STREAM (0x1UL << 20UL)
#define PSYCHO_IOMMU_TAG_SIZE (0x1UL << 19UL)
-#define PSYCHO_IOMMU_TAG_VPAGE 0x7ffffUL
+#define PSYCHO_IOMMU_TAG_VPAGE 0x7ffffULL
#define PSYCHO_IOMMU_DATA_VALID (1UL << 30UL)
#define PSYCHO_IOMMU_DATA_CACHE (1UL << 28UL)
-#define PSYCHO_IOMMU_DATA_PPAGE 0xfffffffUL
+#define PSYCHO_IOMMU_DATA_PPAGE 0xfffffffULL
static void psycho_dump_iommu_tags_and_data(struct pci_pbm_info *pbm,
u64 *tag, u64 *data)
@@ -190,7 +190,7 @@ static void psycho_dump_iommu_tags_and_data(struct pci_pbm_info *pbm,
pbm->name, i,
((data_val & PSYCHO_IOMMU_DATA_VALID) ? 1 : 0),
((data_val & PSYCHO_IOMMU_DATA_CACHE) ? 1 : 0),
- (data_val & PSYCHO_IOMMU_DATA_PPAGE)<<IOMMU_PAGE_SHIFT);
+ (data_val & PSYCHO_IOMMU_DATA_PPAGE) << IOMMU_PAGE_SHIFT);
}
}
@@ -285,20 +285,20 @@ static irqreturn_t psycho_pcierr_intr_other(struct pci_pbm_info *pbm)
return ret;
}
-#define PSYCHO_PCIAFSR_PMA 0x8000000000000000UL
-#define PSYCHO_PCIAFSR_PTA 0x4000000000000000UL
-#define PSYCHO_PCIAFSR_PRTRY 0x2000000000000000UL
-#define PSYCHO_PCIAFSR_PPERR 0x1000000000000000UL
-#define PSYCHO_PCIAFSR_SMA 0x0800000000000000UL
-#define PSYCHO_PCIAFSR_STA 0x0400000000000000UL
-#define PSYCHO_PCIAFSR_SRTRY 0x0200000000000000UL
-#define PSYCHO_PCIAFSR_SPERR 0x0100000000000000UL
-#define PSYCHO_PCIAFSR_RESV1 0x00ff000000000000UL
-#define PSYCHO_PCIAFSR_BMSK 0x0000ffff00000000UL
-#define PSYCHO_PCIAFSR_BLK 0x0000000080000000UL
-#define PSYCHO_PCIAFSR_RESV2 0x0000000040000000UL
-#define PSYCHO_PCIAFSR_MID 0x000000003e000000UL
-#define PSYCHO_PCIAFSR_RESV3 0x0000000001ffffffUL
+#define PSYCHO_PCIAFSR_PMA 0x8000000000000000ULL
+#define PSYCHO_PCIAFSR_PTA 0x4000000000000000ULL
+#define PSYCHO_PCIAFSR_PRTRY 0x2000000000000000ULL
+#define PSYCHO_PCIAFSR_PPERR 0x1000000000000000ULL
+#define PSYCHO_PCIAFSR_SMA 0x0800000000000000ULL
+#define PSYCHO_PCIAFSR_STA 0x0400000000000000ULL
+#define PSYCHO_PCIAFSR_SRTRY 0x0200000000000000ULL
+#define PSYCHO_PCIAFSR_SPERR 0x0100000000000000ULL
+#define PSYCHO_PCIAFSR_RESV1 0x00ff000000000000ULL
+#define PSYCHO_PCIAFSR_BMSK 0x0000ffff00000000ULL
+#define PSYCHO_PCIAFSR_BLK 0x0000000080000000ULL
+#define PSYCHO_PCIAFSR_RESV2 0x0000000040000000ULL
+#define PSYCHO_PCIAFSR_MID 0x000000003e000000ULL
+#define PSYCHO_PCIAFSR_RESV3 0x0000000001ffffffULL
irqreturn_t psycho_pcierr_intr(int irq, void *dev_id)
{
diff --git a/arch/sparc/kernel/sbus.c b/arch/sparc/kernel/sbus.c
index 2ead310..406e087 100644
--- a/arch/sparc/kernel/sbus.c
+++ b/arch/sparc/kernel/sbus.c
@@ -117,6 +117,7 @@ void sbus_set_sbus64(struct device *dev, int bursts)
val |= (1UL << 4UL);
upa_writeq(val, cfg_reg);
}
+EXPORT_SYMBOL(sbus_set_sbus64);
/* INO number to IMAP register offset for SYSIO external IRQ's.
* This should conform to both Sunfire/Wildfire server and Fusion
diff --git a/arch/sparc/kernel/setup_32.c b/arch/sparc/kernel/setup_32.c
index c96c65d..998cadb 100644
--- a/arch/sparc/kernel/setup_32.c
+++ b/arch/sparc/kernel/setup_32.c
@@ -199,7 +199,9 @@ extern unsigned short ram_flags;
extern int root_mountflags;
char reboot_command[COMMAND_LINE_SIZE];
+
enum sparc_cpu sparc_cpu_model;
+EXPORT_SYMBOL(sparc_cpu_model);
struct tt_entry *sparc_ttable;
@@ -391,6 +393,7 @@ void sun_do_break(void)
prom_cmdline();
}
+EXPORT_SYMBOL(sun_do_break);
int stop_a_enabled = 1;
diff --git a/arch/sparc/kernel/setup_64.c b/arch/sparc/kernel/setup_64.c
index 555db74..49d061f 100644
--- a/arch/sparc/kernel/setup_64.c
+++ b/arch/sparc/kernel/setup_64.c
@@ -58,6 +58,7 @@
* operations in asm/ns87303.h
*/
DEFINE_SPINLOCK(ns87303_lock);
+EXPORT_SYMBOL(ns87303_lock);
struct screen_info screen_info = {
0, 0, /* orig-x, orig-y */
@@ -425,5 +426,7 @@ void sun_do_break(void)
prom_cmdline();
}
+EXPORT_SYMBOL(sun_do_break);
int stop_a_enabled = 1;
+EXPORT_SYMBOL(stop_a_enabled);
diff --git a/arch/sparc/kernel/sparc_ksyms_32.c b/arch/sparc/kernel/sparc_ksyms_32.c
index e1e9763..baeab87 100644
--- a/arch/sparc/kernel/sparc_ksyms_32.c
+++ b/arch/sparc/kernel/sparc_ksyms_32.c
@@ -5,49 +5,14 @@
* Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
*/
-/* Tell string.h we don't want memcpy etc. as cpp defines */
-#define EXPORT_SYMTAB_STROPS
-#define PROMLIB_INTERNAL
-
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/smp.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/in6.h>
-#include <linux/spinlock.h>
-#include <linux/mm.h>
-#include <linux/syscalls.h>
-#ifdef CONFIG_PCI
-#include <linux/pci.h>
-#endif
-#include <linux/pm.h>
-#ifdef CONFIG_HIGHMEM
-#include <linux/highmem.h>
-#endif
-#include <asm/oplib.h>
-#include <asm/delay.h>
-#include <asm/system.h>
-#include <asm/auxio.h>
#include <asm/pgtable.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/idprom.h>
-#include <asm/head.h>
-#include <asm/smp.h>
-#include <asm/ptrace.h>
#include <asm/uaccess.h>
-#include <asm/checksum.h>
-#ifdef CONFIG_SBUS
+#include <asm/delay.h>
+#include <asm/head.h>
#include <asm/dma.h>
-#endif
-#include <asm/io-unit.h>
-#include <asm/bug.h>
-
-extern spinlock_t rtc_lock;
struct poll {
int fd;
@@ -55,72 +20,15 @@ struct poll {
short revents;
};
-extern void (*__copy_1page)(void *, const void *);
-extern void __memmove(void *, const void *, __kernel_size_t);
-extern void (*bzero_1page)(void *);
-extern void *__bzero(void *, size_t);
-extern void *__memscan_zero(void *, size_t);
-extern void *__memscan_generic(void *, int, size_t);
-extern int __strncmp(const char *, const char *, __kernel_size_t);
-
-extern int __ashrdi3(int, int);
-extern int __ashldi3(int, int);
-extern int __lshrdi3(int, int);
-extern int __muldi3(int, int);
-extern int __divdi3(int, int);
-
-/* Private functions with odd calling conventions. */
-extern void ___atomic24_add(void);
-extern void ___atomic24_sub(void);
-extern void ___rw_read_enter(void);
-extern void ___rw_read_try(void);
-extern void ___rw_read_exit(void);
-extern void ___rw_write_enter(void);
-
-/* Alias functions whose names begin with "." and export the aliases.
- * The module references will be fixed up by module_frob_arch_sections.
- */
-extern int _Div(int, int);
-extern int _Mul(int, int);
-extern int _Rem(int, int);
-extern unsigned _Udiv(unsigned, unsigned);
-extern unsigned _Umul(unsigned, unsigned);
-extern unsigned _Urem(unsigned, unsigned);
-
-/* used by various drivers */
-EXPORT_SYMBOL(sparc_cpu_model);
-EXPORT_SYMBOL(kernel_thread);
-#ifdef CONFIG_SMP
-// XXX find what uses (or used) these. AV: see asm/spinlock.h
-EXPORT_SYMBOL(___rw_read_enter);
-EXPORT_SYMBOL(___rw_read_try);
-EXPORT_SYMBOL(___rw_read_exit);
-EXPORT_SYMBOL(___rw_write_enter);
-#endif
-
-EXPORT_SYMBOL(sparc_valid_addr_bitmap);
-EXPORT_SYMBOL(phys_base);
-EXPORT_SYMBOL(pfn_base);
-
-/* Atomic operations. */
-EXPORT_SYMBOL(___atomic24_add);
-EXPORT_SYMBOL(___atomic24_sub);
-
-/* Per-CPU information table */
-EXPORT_PER_CPU_SYMBOL(__cpu_data);
-
-#ifdef CONFIG_SMP
-/* IRQ implementation. */
-EXPORT_SYMBOL(synchronize_irq);
-#endif
-
+/* from entry.S */
EXPORT_SYMBOL(__udelay);
EXPORT_SYMBOL(__ndelay);
-EXPORT_SYMBOL(rtc_lock);
-EXPORT_SYMBOL(set_auxio);
-EXPORT_SYMBOL(get_auxio);
-EXPORT_SYMBOL(io_remap_pfn_range);
+/* from head_32.S */
+EXPORT_SYMBOL(__ret_efault);
+EXPORT_SYMBOL(empty_zero_page);
+
+/* Defined using magic */
#ifndef CONFIG_SMP
EXPORT_SYMBOL(BTFIXUP_CALL(___xchg32));
#else
@@ -132,122 +40,7 @@ EXPORT_SYMBOL(BTFIXUP_CALL(mmu_get_scsi_sgl));
EXPORT_SYMBOL(BTFIXUP_CALL(mmu_get_scsi_one));
EXPORT_SYMBOL(BTFIXUP_CALL(mmu_release_scsi_sgl));
EXPORT_SYMBOL(BTFIXUP_CALL(mmu_release_scsi_one));
-
EXPORT_SYMBOL(BTFIXUP_CALL(pgprot_noncached));
-#ifdef CONFIG_SBUS
-EXPORT_SYMBOL(sbus_set_sbus64);
-#endif
-#ifdef CONFIG_PCI
-EXPORT_SYMBOL(insb);
-EXPORT_SYMBOL(outsb);
-EXPORT_SYMBOL(insw);
-EXPORT_SYMBOL(outsw);
-EXPORT_SYMBOL(insl);
-EXPORT_SYMBOL(outsl);
-EXPORT_SYMBOL(pci_alloc_consistent);
-EXPORT_SYMBOL(pci_free_consistent);
-EXPORT_SYMBOL(pci_map_single);
-EXPORT_SYMBOL(pci_unmap_single);
-EXPORT_SYMBOL(pci_dma_sync_single_for_cpu);
-EXPORT_SYMBOL(pci_dma_sync_single_for_device);
-EXPORT_SYMBOL(pci_dma_sync_sg_for_cpu);
-EXPORT_SYMBOL(pci_dma_sync_sg_for_device);
-EXPORT_SYMBOL(pci_map_sg);
-EXPORT_SYMBOL(pci_unmap_sg);
-EXPORT_SYMBOL(pci_map_page);
-EXPORT_SYMBOL(pci_unmap_page);
-/* Actually, ioremap/iounmap are not PCI specific. But it is ok for drivers. */
-EXPORT_SYMBOL(ioremap);
-EXPORT_SYMBOL(iounmap);
-#endif
-
-/* in arch/sparc/mm/highmem.c */
-#ifdef CONFIG_HIGHMEM
-EXPORT_SYMBOL(kmap_atomic);
-EXPORT_SYMBOL(kunmap_atomic);
-#endif
-
-/* prom symbols */
-EXPORT_SYMBOL(idprom);
-EXPORT_SYMBOL(prom_root_node);
-EXPORT_SYMBOL(prom_getchild);
-EXPORT_SYMBOL(prom_getsibling);
-EXPORT_SYMBOL(prom_searchsiblings);
-EXPORT_SYMBOL(prom_firstprop);
-EXPORT_SYMBOL(prom_nextprop);
-EXPORT_SYMBOL(prom_getproplen);
-EXPORT_SYMBOL(prom_getproperty);
-EXPORT_SYMBOL(prom_node_has_property);
-EXPORT_SYMBOL(prom_setprop);
+/* Exporting a symbol from /init/main.c */
EXPORT_SYMBOL(saved_command_line);
-EXPORT_SYMBOL(prom_apply_obio_ranges);
-EXPORT_SYMBOL(prom_feval);
-EXPORT_SYMBOL(prom_getbool);
-EXPORT_SYMBOL(prom_getstring);
-EXPORT_SYMBOL(prom_getint);
-EXPORT_SYMBOL(prom_getintdefault);
-EXPORT_SYMBOL(prom_finddevice);
-EXPORT_SYMBOL(romvec);
-EXPORT_SYMBOL(__prom_getchild);
-EXPORT_SYMBOL(__prom_getsibling);
-
-/* sparc library symbols */
-EXPORT_SYMBOL(memscan);
-EXPORT_SYMBOL(strlen);
-EXPORT_SYMBOL(strncmp);
-EXPORT_SYMBOL(page_kernel);
-
-/* Special internal versions of library functions. */
-EXPORT_SYMBOL(__copy_1page);
-EXPORT_SYMBOL(__memcpy);
-EXPORT_SYMBOL(__memset);
-EXPORT_SYMBOL(bzero_1page);
-EXPORT_SYMBOL(__bzero);
-EXPORT_SYMBOL(__memscan_zero);
-EXPORT_SYMBOL(__memscan_generic);
-EXPORT_SYMBOL(__strncmp);
-EXPORT_SYMBOL(__memmove);
-
-/* Moving data to/from userspace. */
-EXPORT_SYMBOL(__copy_user);
-EXPORT_SYMBOL(__strncpy_from_user);
-EXPORT_SYMBOL(__strnlen_user);
-
-/* Networking helper routines. */
-EXPORT_SYMBOL(__csum_partial_copy_sparc_generic);
-EXPORT_SYMBOL(csum_partial);
-
-/* Cache flushing. */
-EXPORT_SYMBOL(sparc_flush_page_to_ram);
-
-/* For when serial stuff is built as modules. */
-EXPORT_SYMBOL(sun_do_break);
-
-EXPORT_SYMBOL(__ret_efault);
-
-EXPORT_SYMBOL(memcmp);
-EXPORT_SYMBOL(memcpy);
-EXPORT_SYMBOL(memset);
-EXPORT_SYMBOL(memmove);
-EXPORT_SYMBOL(__ashrdi3);
-EXPORT_SYMBOL(__ashldi3);
-EXPORT_SYMBOL(__lshrdi3);
-EXPORT_SYMBOL(__muldi3);
-EXPORT_SYMBOL(__divdi3);
-
-EXPORT_SYMBOL(_Rem);
-EXPORT_SYMBOL(_Urem);
-EXPORT_SYMBOL(_Mul);
-EXPORT_SYMBOL(_Umul);
-EXPORT_SYMBOL(_Div);
-EXPORT_SYMBOL(_Udiv);
-
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-EXPORT_SYMBOL(do_BUG);
-#endif
-
-/* Sun Power Management Idle Handler */
-EXPORT_SYMBOL(pm_idle);
-
-EXPORT_SYMBOL(empty_zero_page);
diff --git a/arch/sparc/kernel/sparc_ksyms_64.c b/arch/sparc/kernel/sparc_ksyms_64.c
index 0133211..da8f804 100644
--- a/arch/sparc/kernel/sparc_ksyms_64.c
+++ b/arch/sparc/kernel/sparc_ksyms_64.c
@@ -5,50 +5,16 @@
* Copyright (C) 1999 Jakub Jelinek (jj@ultra.linux.cz)
*/
-/* Tell string.h we don't want memcpy etc. as cpp defines */
-#define EXPORT_SYMTAB_STROPS
-#define PROMLIB_INTERNAL
-
#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/string.h>
-#include <linux/sched.h>
-#include <linux/in6.h>
#include <linux/pci.h>
-#include <linux/interrupt.h>
-#include <linux/fs_struct.h>
-#include <linux/fs.h>
-#include <linux/mm.h>
-#include <linux/socket.h>
-#include <linux/syscalls.h>
-#include <linux/percpu.h>
#include <linux/init.h>
-#include <linux/rwsem.h>
-#include <net/compat.h>
-#include <asm/oplib.h>
+#include <asm/spinlock.h>
#include <asm/system.h>
-#include <asm/auxio.h>
-#include <asm/pgtable.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/idprom.h>
-#include <asm/elf.h>
-#include <asm/head.h>
-#include <asm/smp.h>
-#include <asm/ptrace.h>
-#include <asm/uaccess.h>
-#include <asm/checksum.h>
-#include <asm/fpumacro.h>
-#include <asm/pgalloc.h>
-#include <asm/cacheflush.h>
-#ifdef CONFIG_SBUS
-#include <asm/dma.h>
-#endif
-#include <asm/ns87303.h>
-#include <asm/timer.h>
#include <asm/cpudata.h>
-#include <asm/ftrace.h>
+#include <asm/uaccess.h>
+#include <asm/spitfire.h>
+#include <asm/oplib.h>
#include <asm/hypervisor.h>
struct poll {
@@ -57,42 +23,6 @@ struct poll {
short revents;
};
-extern void die_if_kernel(char *str, struct pt_regs *regs);
-extern pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
-extern void *__bzero(void *, size_t);
-extern void *__memscan_zero(void *, size_t);
-extern void *__memscan_generic(void *, int, size_t);
-extern __kernel_size_t strlen(const char *);
-extern void sys_sigsuspend(void);
-extern int compat_sys_ioctl(unsigned int fd, unsigned int cmd, u32 arg);
-extern int (*handle_mathemu)(struct pt_regs *, struct fpustate *);
-extern long sparc32_open(const char __user * filename, int flags, int mode);
-extern int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
- unsigned long pfn, unsigned long size, pgprot_t prot);
-
-extern int __ashrdi3(int, int);
-
-extern int dump_fpu (struct pt_regs * regs, elf_fpregset_t * fpregs);
-
-extern void xor_vis_2(unsigned long, unsigned long *, unsigned long *);
-extern void xor_vis_3(unsigned long, unsigned long *, unsigned long *,
- unsigned long *);
-extern void xor_vis_4(unsigned long, unsigned long *, unsigned long *,
- unsigned long *, unsigned long *);
-extern void xor_vis_5(unsigned long, unsigned long *, unsigned long *,
- unsigned long *, unsigned long *, unsigned long *);
-
-extern void xor_niagara_2(unsigned long, unsigned long *, unsigned long *);
-extern void xor_niagara_3(unsigned long, unsigned long *, unsigned long *,
- unsigned long *);
-extern void xor_niagara_4(unsigned long, unsigned long *, unsigned long *,
- unsigned long *, unsigned long *);
-extern void xor_niagara_5(unsigned long, unsigned long *, unsigned long *,
- unsigned long *, unsigned long *, unsigned long *);
-
-/* Per-CPU information table */
-EXPORT_PER_CPU_SYMBOL(__cpu_data);
-
/* used by various drivers */
#ifdef CONFIG_SMP
/* Out of line rw-locking implementation. */
@@ -103,68 +33,24 @@ EXPORT_SYMBOL(__write_unlock);
EXPORT_SYMBOL(__write_trylock);
#endif /* CONFIG_SMP */
-#ifdef CONFIG_MCOUNT
-EXPORT_SYMBOL(_mcount);
-#endif
-
-EXPORT_SYMBOL(sparc64_get_clock_tick);
-
-/* RW semaphores */
-EXPORT_SYMBOL(__down_read);
-EXPORT_SYMBOL(__down_read_trylock);
-EXPORT_SYMBOL(__down_write);
-EXPORT_SYMBOL(__down_write_trylock);
-EXPORT_SYMBOL(__up_read);
-EXPORT_SYMBOL(__up_write);
-EXPORT_SYMBOL(__downgrade_write);
-
-/* Atomic counter implementation. */
-EXPORT_SYMBOL(atomic_add);
-EXPORT_SYMBOL(atomic_add_ret);
-EXPORT_SYMBOL(atomic_sub);
-EXPORT_SYMBOL(atomic_sub_ret);
-EXPORT_SYMBOL(atomic64_add);
-EXPORT_SYMBOL(atomic64_add_ret);
-EXPORT_SYMBOL(atomic64_sub);
-EXPORT_SYMBOL(atomic64_sub_ret);
-
-/* Atomic bit operations. */
-EXPORT_SYMBOL(test_and_set_bit);
-EXPORT_SYMBOL(test_and_clear_bit);
-EXPORT_SYMBOL(test_and_change_bit);
-EXPORT_SYMBOL(set_bit);
-EXPORT_SYMBOL(clear_bit);
-EXPORT_SYMBOL(change_bit);
-
+/* from helpers.S */
EXPORT_SYMBOL(__flushw_user);
+EXPORT_SYMBOL_GPL(real_hard_smp_processor_id);
+/* from head_64.S */
+EXPORT_SYMBOL(__ret_efault);
EXPORT_SYMBOL(tlb_type);
EXPORT_SYMBOL(sun4v_chip_type);
-EXPORT_SYMBOL(get_fb_unmapped_area);
-EXPORT_SYMBOL(flush_icache_range);
-
-EXPORT_SYMBOL(flush_dcache_page);
-#ifdef DCACHE_ALIASING_POSSIBLE
-EXPORT_SYMBOL(__flush_dcache_range);
-#endif
+EXPORT_SYMBOL(prom_root_node);
+/* from hvcalls.S */
EXPORT_SYMBOL(sun4v_niagara_getperf);
EXPORT_SYMBOL(sun4v_niagara_setperf);
EXPORT_SYMBOL(sun4v_niagara2_getperf);
EXPORT_SYMBOL(sun4v_niagara2_setperf);
-EXPORT_SYMBOL(auxio_set_led);
-EXPORT_SYMBOL(auxio_set_lte);
-#ifdef CONFIG_SBUS
-EXPORT_SYMBOL(sbus_set_sbus64);
-#endif
-EXPORT_SYMBOL(outsb);
-EXPORT_SYMBOL(outsw);
-EXPORT_SYMBOL(outsl);
-EXPORT_SYMBOL(insb);
-EXPORT_SYMBOL(insw);
-EXPORT_SYMBOL(insl);
#ifdef CONFIG_PCI
+/* inline functions in asm/pci_64.h */
EXPORT_SYMBOL(pci_alloc_consistent);
EXPORT_SYMBOL(pci_free_consistent);
EXPORT_SYMBOL(pci_map_single);
@@ -173,112 +59,7 @@ EXPORT_SYMBOL(pci_map_sg);
EXPORT_SYMBOL(pci_unmap_sg);
EXPORT_SYMBOL(pci_dma_sync_single_for_cpu);
EXPORT_SYMBOL(pci_dma_sync_sg_for_cpu);
-EXPORT_SYMBOL(pci_dma_supported);
#endif
-/* I/O device mmaping on Sparc64. */
-EXPORT_SYMBOL(io_remap_pfn_range);
-
-EXPORT_SYMBOL(dump_fpu);
-
-/* math-emu wants this */
-EXPORT_SYMBOL(die_if_kernel);
-
-/* Kernel thread creation. */
-EXPORT_SYMBOL(kernel_thread);
-
-/* prom symbols */
-EXPORT_SYMBOL(idprom);
-EXPORT_SYMBOL(prom_root_node);
-EXPORT_SYMBOL(prom_getchild);
-EXPORT_SYMBOL(prom_getsibling);
-EXPORT_SYMBOL(prom_searchsiblings);
-EXPORT_SYMBOL(prom_firstprop);
-EXPORT_SYMBOL(prom_nextprop);
-EXPORT_SYMBOL(prom_getproplen);
-EXPORT_SYMBOL(prom_getproperty);
-EXPORT_SYMBOL(prom_node_has_property);
-EXPORT_SYMBOL(prom_setprop);
+/* Exporting a symbol from /init/main.c */
EXPORT_SYMBOL(saved_command_line);
-EXPORT_SYMBOL(prom_finddevice);
-EXPORT_SYMBOL(prom_feval);
-EXPORT_SYMBOL(prom_getbool);
-EXPORT_SYMBOL(prom_getstring);
-EXPORT_SYMBOL(prom_getint);
-EXPORT_SYMBOL(prom_getintdefault);
-EXPORT_SYMBOL(__prom_getchild);
-EXPORT_SYMBOL(__prom_getsibling);
-
-/* sparc library symbols */
-EXPORT_SYMBOL(strlen);
-EXPORT_SYMBOL(__strlen_user);
-EXPORT_SYMBOL(__strnlen_user);
-
-/* Special internal versions of library functions. */
-EXPORT_SYMBOL(_clear_page);
-EXPORT_SYMBOL(clear_user_page);
-EXPORT_SYMBOL(copy_user_page);
-EXPORT_SYMBOL(__bzero);
-EXPORT_SYMBOL(__memscan_zero);
-EXPORT_SYMBOL(__memscan_generic);
-EXPORT_SYMBOL(__memset);
-
-EXPORT_SYMBOL(csum_partial);
-EXPORT_SYMBOL(csum_partial_copy_nocheck);
-EXPORT_SYMBOL(__csum_partial_copy_from_user);
-EXPORT_SYMBOL(__csum_partial_copy_to_user);
-EXPORT_SYMBOL(ip_fast_csum);
-
-/* Moving data to/from/in userspace. */
-EXPORT_SYMBOL(___copy_to_user);
-EXPORT_SYMBOL(___copy_from_user);
-EXPORT_SYMBOL(___copy_in_user);
-EXPORT_SYMBOL(copy_to_user_fixup);
-EXPORT_SYMBOL(copy_from_user_fixup);
-EXPORT_SYMBOL(copy_in_user_fixup);
-EXPORT_SYMBOL(__strncpy_from_user);
-EXPORT_SYMBOL(__clear_user);
-
-/* Various address conversion macros use this. */
-EXPORT_SYMBOL(sparc64_valid_addr_bitmap);
-
-/* No version information on this, heavily used in inline asm,
- * and will always be 'void __ret_efault(void)'.
- */
-EXPORT_SYMBOL(__ret_efault);
-
-/* No version information on these, as gcc produces such symbols. */
-EXPORT_SYMBOL(memcmp);
-EXPORT_SYMBOL(memcpy);
-EXPORT_SYMBOL(memset);
-EXPORT_SYMBOL(memmove);
-EXPORT_SYMBOL(strncmp);
-
-void VISenter(void);
-/* RAID code needs this */
-EXPORT_SYMBOL(VISenter);
-
-/* for input/keybdev */
-EXPORT_SYMBOL(sun_do_break);
-EXPORT_SYMBOL(stop_a_enabled);
-
-#ifdef CONFIG_DEBUG_BUGVERBOSE
-EXPORT_SYMBOL(do_BUG);
-#endif
-
-/* for ns8703 */
-EXPORT_SYMBOL(ns87303_lock);
-
-EXPORT_SYMBOL(tick_ops);
-
-EXPORT_SYMBOL(xor_vis_2);
-EXPORT_SYMBOL(xor_vis_3);
-EXPORT_SYMBOL(xor_vis_4);
-EXPORT_SYMBOL(xor_vis_5);
-
-EXPORT_SYMBOL(xor_niagara_2);
-EXPORT_SYMBOL(xor_niagara_3);
-EXPORT_SYMBOL(xor_niagara_4);
-EXPORT_SYMBOL(xor_niagara_5);
-
-EXPORT_SYMBOL_GPL(real_hard_smp_processor_id);
diff --git a/arch/sparc/kernel/sun4d_smp.c b/arch/sparc/kernel/sun4d_smp.c
index 16ab0cb..50afaed 100644
--- a/arch/sparc/kernel/sun4d_smp.c
+++ b/arch/sparc/kernel/sun4d_smp.c
@@ -60,7 +60,7 @@ extern int __smp4d_processor_id(void);
#define SMP_PRINTK(x)
#endif
-static inline unsigned long swap(volatile unsigned long *ptr, unsigned long val)
+static inline unsigned long sun4d_swap(volatile unsigned long *ptr, unsigned long val)
{
__asm__ __volatile__("swap [%1], %0\n\t" :
"=&r" (val), "=&r" (ptr) :
@@ -115,7 +115,7 @@ void __cpuinit smp4d_callin(void)
local_flush_tlb_all();
/* Allow master to continue. */
- swap((unsigned long *)&cpu_callin_map[cpuid], 1);
+ sun4d_swap((unsigned long *)&cpu_callin_map[cpuid], 1);
local_flush_cache_all();
local_flush_tlb_all();
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index 39749e3..09058fc 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -23,6 +23,7 @@
#include <linux/ipc.h>
#include <linux/personality.h>
#include <linux/random.h>
+#include <linux/module.h>
#include <asm/uaccess.h>
#include <asm/utrap.h>
@@ -354,6 +355,7 @@ unsigned long get_fb_unmapped_area(struct file *filp, unsigned long orig_addr, u
return addr;
}
+EXPORT_SYMBOL(get_fb_unmapped_area);
/* Essentially the same as PowerPC... */
void arch_pick_mmap_layout(struct mm_struct *mm)
diff --git a/arch/sparc/kernel/time_32.c b/arch/sparc/kernel/time_32.c
index 00f7383..614ac7b 100644
--- a/arch/sparc/kernel/time_32.c
+++ b/arch/sparc/kernel/time_32.c
@@ -48,6 +48,8 @@
#include "irq.h"
DEFINE_SPINLOCK(rtc_lock);
+EXPORT_SYMBOL(rtc_lock);
+
static int set_rtc_mmss(unsigned long);
static int sbus_do_settimeofday(struct timespec *tv);
diff --git a/arch/sparc/kernel/time_64.c b/arch/sparc/kernel/time_64.c
index 54405d3..db310aa 100644
--- a/arch/sparc/kernel/time_64.c
+++ b/arch/sparc/kernel/time_64.c
@@ -176,6 +176,7 @@ static struct sparc64_tick_ops tick_operations __read_mostly = {
};
struct sparc64_tick_ops *tick_ops __read_mostly = &tick_operations;
+EXPORT_SYMBOL(tick_ops);
static void stick_disable_irq(void)
{
@@ -639,6 +640,7 @@ unsigned long sparc64_get_clock_tick(unsigned int cpu)
return ft->clock_tick_ref;
return cpu_data(cpu).clock_tick;
}
+EXPORT_SYMBOL(sparc64_get_clock_tick);
#ifdef CONFIG_CPU_FREQ
@@ -727,7 +729,7 @@ void timer_interrupt(int irq, struct pt_regs *regs)
irq_enter();
- kstat_this_cpu.irqs[0]++;
+ kstat_incr_irqs_this_cpu(0, irq_to_desc(0));
if (unlikely(!evt->event_handler)) {
printk(KERN_WARNING
diff --git a/arch/sparc/kernel/traps_32.c b/arch/sparc/kernel/traps_32.c
index 213645b..3582833 100644
--- a/arch/sparc/kernel/traps_32.c
+++ b/arch/sparc/kernel/traps_32.c
@@ -424,6 +424,7 @@ void do_BUG(const char *file, int line)
// bust_spinlocks(1); XXX Not in our original BUG()
printk("kernel BUG at %s:%d!\n", file, line);
}
+EXPORT_SYMBOL(do_BUG);
#endif
/* Since we have our mappings set up, on multiprocessors we can spin them
diff --git a/arch/sparc/kernel/traps_64.c b/arch/sparc/kernel/traps_64.c
index bca3b4e..c2d153d 100644
--- a/arch/sparc/kernel/traps_64.c
+++ b/arch/sparc/kernel/traps_64.c
@@ -128,6 +128,7 @@ void do_BUG(const char *file, int line)
bust_spinlocks(1);
printk("kernel BUG at %s:%d!\n", file, line);
}
+EXPORT_SYMBOL(do_BUG);
#endif
static DEFINE_SPINLOCK(dimm_handler_lock);
@@ -2261,6 +2262,7 @@ void die_if_kernel(char *str, struct pt_regs *regs)
do_exit(SIGKILL);
do_exit(SIGSEGV);
}
+EXPORT_SYMBOL(die_if_kernel);
#define VIS_OPCODE_MASK ((0x3 << 30) | (0x3f << 19))
#define VIS_OPCODE_VAL ((0x2 << 30) | (0x36 << 19))
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c
index f164d5a..3792099 100644
--- a/arch/sparc/kernel/unaligned_64.c
+++ b/arch/sparc/kernel/unaligned_64.c
@@ -589,7 +589,6 @@ void handle_lddfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr
unsigned long pc = regs->tpc;
unsigned long tstate = regs->tstate;
u32 insn;
- u32 first, second;
u64 value;
u8 freg;
int flag;
@@ -601,19 +600,20 @@ void handle_lddfmna(struct pt_regs *regs, unsigned long sfar, unsigned long sfsr
pc = (u32)pc;
if (get_user(insn, (u32 __user *) pc) != -EFAULT) {
int asi = decode_asi(insn, regs);
+ u32 first, second;
int err;
if ((asi > ASI_SNFL) ||
(asi < ASI_P))
goto daex;
+ first = second = 0;
err = get_user(first, (u32 __user *)sfar);
if (!err)
err = get_user(second, (u32 __user *)(sfar + 4));
if (err) {
- if (asi & 0x2) /* NF */ {
- first = 0; second = 0;
- } else
+ if (!(asi & 0x2))
goto daex;
+ first = second = 0;
}
save_and_clear_fpu();
freg = ((insn >> 25) & 0x1e) | ((insn >> 20) & 0x20);
diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile
index 375016e..273fc85 100644
--- a/arch/sparc/lib/Makefile
+++ b/arch/sparc/lib/Makefile
@@ -42,3 +42,4 @@ lib-$(CONFIG_SPARC64) += mcount.o ipcsum.o xor.o
obj-y += iomap.o
obj-$(CONFIG_SPARC32) += atomic32.o
+obj-y += ksyms.o
diff --git a/arch/sparc/lib/PeeCeeI.c b/arch/sparc/lib/PeeCeeI.c
index 46053e6..6529f86 100644
--- a/arch/sparc/lib/PeeCeeI.c
+++ b/arch/sparc/lib/PeeCeeI.c
@@ -4,6 +4,8 @@
* Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
*/
+#include <linux/module.h>
+
#include <asm/io.h>
#include <asm/byteorder.h>
@@ -15,6 +17,7 @@ void outsb(unsigned long __addr, const void *src, unsigned long count)
while (count--)
outb(*p++, addr);
}
+EXPORT_SYMBOL(outsb);
void outsw(unsigned long __addr, const void *src, unsigned long count)
{
@@ -25,6 +28,7 @@ void outsw(unsigned long __addr, const void *src, unsigned long count)
src += sizeof(u16);
}
}
+EXPORT_SYMBOL(outsw);
void outsl(unsigned long __addr, const void *src, unsigned long count)
{
@@ -78,6 +82,7 @@ void outsl(unsigned long __addr, const void *src, unsigned long count)
break;
}
}
+EXPORT_SYMBOL(outsl);
void insb(unsigned long __addr, void *dst, unsigned long count)
{
@@ -105,6 +110,7 @@ void insb(unsigned long __addr, void *dst, unsigned long count)
*pb++ = inb(addr);
}
}
+EXPORT_SYMBOL(insb);
void insw(unsigned long __addr, void *dst, unsigned long count)
{
@@ -132,6 +138,7 @@ void insw(unsigned long __addr, void *dst, unsigned long count)
*ps = le16_to_cpu(inw(addr));
}
}
+EXPORT_SYMBOL(insw);
void insl(unsigned long __addr, void *dst, unsigned long count)
{
@@ -200,4 +207,5 @@ void insl(unsigned long __addr, void *dst, unsigned long count)
}
}
}
+EXPORT_SYMBOL(insl);
diff --git a/arch/sparc/lib/ksyms.c b/arch/sparc/lib/ksyms.c
new file mode 100644
index 0000000..704b126
--- /dev/null
+++ b/arch/sparc/lib/ksyms.c
@@ -0,0 +1,196 @@
+/*
+ * Export of symbols defined in assembler
+ */
+
+/* Tell string.h we don't want memcpy etc. as cpp defines */
+#define EXPORT_SYMTAB_STROPS
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/types.h>
+
+#include <asm/checksum.h>
+#include <asm/uaccess.h>
+#include <asm/ftrace.h>
+
+/* string functions */
+EXPORT_SYMBOL(strlen);
+EXPORT_SYMBOL(__strlen_user);
+EXPORT_SYMBOL(__strnlen_user);
+EXPORT_SYMBOL(strncmp);
+
+/* mem* functions */
+extern void *__memscan_zero(void *, size_t);
+extern void *__memscan_generic(void *, int, size_t);
+extern void *__bzero(void *, size_t);
+
+EXPORT_SYMBOL(memscan);
+EXPORT_SYMBOL(__memscan_zero);
+EXPORT_SYMBOL(__memscan_generic);
+EXPORT_SYMBOL(memcmp);
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(memset);
+EXPORT_SYMBOL(__memset);
+EXPORT_SYMBOL(memmove);
+EXPORT_SYMBOL(__bzero);
+
+/* Moving data to/from/in userspace. */
+EXPORT_SYMBOL(__strncpy_from_user);
+
+/* Networking helper routines. */
+EXPORT_SYMBOL(csum_partial);
+
+#ifdef CONFIG_MCOUNT
+EXPORT_SYMBOL(_mcount);
+#endif
+
+/*
+ * sparc
+ */
+#ifdef CONFIG_SPARC32
+extern int __ashrdi3(int, int);
+extern int __ashldi3(int, int);
+extern int __lshrdi3(int, int);
+extern int __muldi3(int, int);
+extern int __divdi3(int, int);
+
+extern void (*__copy_1page)(void *, const void *);
+extern void (*bzero_1page)(void *);
+
+extern int __strncmp(const char *, const char *, __kernel_size_t);
+
+extern void ___rw_read_enter(void);
+extern void ___rw_read_try(void);
+extern void ___rw_read_exit(void);
+extern void ___rw_write_enter(void);
+extern void ___atomic24_add(void);
+extern void ___atomic24_sub(void);
+
+/* Alias functions whose names begin with "." and export the aliases.
+ * The module references will be fixed up by module_frob_arch_sections.
+ */
+extern int _Div(int, int);
+extern int _Mul(int, int);
+extern int _Rem(int, int);
+extern unsigned _Udiv(unsigned, unsigned);
+extern unsigned _Umul(unsigned, unsigned);
+extern unsigned _Urem(unsigned, unsigned);
+
+/* Networking helper routines. */
+EXPORT_SYMBOL(__csum_partial_copy_sparc_generic);
+
+/* Special internal versions of library functions. */
+EXPORT_SYMBOL(__copy_1page);
+EXPORT_SYMBOL(__memcpy);
+EXPORT_SYMBOL(__memmove);
+EXPORT_SYMBOL(bzero_1page);
+
+/* string functions */
+EXPORT_SYMBOL(__strncmp);
+
+/* Moving data to/from/in userspace. */
+EXPORT_SYMBOL(__copy_user);
+
+/* Used by asm/spinlock.h */
+#ifdef CONFIG_SMP
+EXPORT_SYMBOL(___rw_read_enter);
+EXPORT_SYMBOL(___rw_read_try);
+EXPORT_SYMBOL(___rw_read_exit);
+EXPORT_SYMBOL(___rw_write_enter);
+#endif
+
+/* Atomic operations. */
+EXPORT_SYMBOL(___atomic24_add);
+EXPORT_SYMBOL(___atomic24_sub);
+
+EXPORT_SYMBOL(__ashrdi3);
+EXPORT_SYMBOL(__ashldi3);
+EXPORT_SYMBOL(__lshrdi3);
+EXPORT_SYMBOL(__muldi3);
+EXPORT_SYMBOL(__divdi3);
+
+EXPORT_SYMBOL(_Rem);
+EXPORT_SYMBOL(_Urem);
+EXPORT_SYMBOL(_Mul);
+EXPORT_SYMBOL(_Umul);
+EXPORT_SYMBOL(_Div);
+EXPORT_SYMBOL(_Udiv);
+#endif
+
+/*
+ * sparc64
+ */
+#ifdef CONFIG_SPARC64
+/* Networking helper routines. */
+EXPORT_SYMBOL(csum_partial_copy_nocheck);
+EXPORT_SYMBOL(__csum_partial_copy_from_user);
+EXPORT_SYMBOL(__csum_partial_copy_to_user);
+EXPORT_SYMBOL(ip_fast_csum);
+
+/* Moving data to/from/in userspace. */
+EXPORT_SYMBOL(___copy_to_user);
+EXPORT_SYMBOL(___copy_from_user);
+EXPORT_SYMBOL(___copy_in_user);
+EXPORT_SYMBOL(__clear_user);
+
+/* RW semaphores */
+EXPORT_SYMBOL(__down_read);
+EXPORT_SYMBOL(__down_read_trylock);
+EXPORT_SYMBOL(__down_write);
+EXPORT_SYMBOL(__down_write_trylock);
+EXPORT_SYMBOL(__up_read);
+EXPORT_SYMBOL(__up_write);
+EXPORT_SYMBOL(__downgrade_write);
+
+/* Atomic counter implementation. */
+EXPORT_SYMBOL(atomic_add);
+EXPORT_SYMBOL(atomic_add_ret);
+EXPORT_SYMBOL(atomic_sub);
+EXPORT_SYMBOL(atomic_sub_ret);
+EXPORT_SYMBOL(atomic64_add);
+EXPORT_SYMBOL(atomic64_add_ret);
+EXPORT_SYMBOL(atomic64_sub);
+EXPORT_SYMBOL(atomic64_sub_ret);
+
+/* Atomic bit operations. */
+EXPORT_SYMBOL(test_and_set_bit);
+EXPORT_SYMBOL(test_and_clear_bit);
+EXPORT_SYMBOL(test_and_change_bit);
+EXPORT_SYMBOL(set_bit);
+EXPORT_SYMBOL(clear_bit);
+EXPORT_SYMBOL(change_bit);
+
+/* Special internal versions of library functions. */
+EXPORT_SYMBOL(_clear_page);
+EXPORT_SYMBOL(clear_user_page);
+EXPORT_SYMBOL(copy_user_page);
+
+/* RAID code needs this */
+void VISenter(void);
+EXPORT_SYMBOL(VISenter);
+
+extern void xor_vis_2(unsigned long, unsigned long *, unsigned long *);
+extern void xor_vis_3(unsigned long, unsigned long *, unsigned long *,
+ unsigned long *);
+extern void xor_vis_4(unsigned long, unsigned long *, unsigned long *,
+ unsigned long *, unsigned long *);
+extern void xor_vis_5(unsigned long, unsigned long *, unsigned long *,
+ unsigned long *, unsigned long *, unsigned long *);
+EXPORT_SYMBOL(xor_vis_2);
+EXPORT_SYMBOL(xor_vis_3);
+EXPORT_SYMBOL(xor_vis_4);
+EXPORT_SYMBOL(xor_vis_5);
+
+extern void xor_niagara_2(unsigned long, unsigned long *, unsigned long *);
+extern void xor_niagara_3(unsigned long, unsigned long *, unsigned long *,
+ unsigned long *);
+extern void xor_niagara_4(unsigned long, unsigned long *, unsigned long *,
+ unsigned long *, unsigned long *);
+extern void xor_niagara_5(unsigned long, unsigned long *, unsigned long *,
+ unsigned long *, unsigned long *, unsigned long *);
+
+EXPORT_SYMBOL(xor_niagara_2);
+EXPORT_SYMBOL(xor_niagara_3);
+EXPORT_SYMBOL(xor_niagara_4);
+EXPORT_SYMBOL(xor_niagara_5);
+#endif
diff --git a/arch/sparc/lib/user_fixup.c b/arch/sparc/lib/user_fixup.c
index 05a361b..ac96ae2 100644
--- a/arch/sparc/lib/user_fixup.c
+++ b/arch/sparc/lib/user_fixup.c
@@ -7,6 +7,8 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
+#include <linux/module.h>
+
#include <asm/uaccess.h>
/* Calculating the exact fault address when using
@@ -40,6 +42,7 @@ unsigned long copy_from_user_fixup(void *to, const void __user *from, unsigned l
return size;
}
+EXPORT_SYMBOL(copy_from_user_fixup);
unsigned long copy_to_user_fixup(void __user *to, const void *from, unsigned long size)
{
@@ -47,6 +50,7 @@ unsigned long copy_to_user_fixup(void __user *to, const void *from, unsigned lon
return compute_size((unsigned long) to, size, &offset);
}
+EXPORT_SYMBOL(copy_to_user_fixup);
unsigned long copy_in_user_fixup(void __user *to, void __user *from, unsigned long size)
{
@@ -64,3 +68,4 @@ unsigned long copy_in_user_fixup(void __user *to, void __user *from, unsigned lo
return size;
}
+EXPORT_SYMBOL(copy_in_user_fixup);
diff --git a/arch/sparc/mm/generic_32.c b/arch/sparc/mm/generic_32.c
index a289261..5edcac1 100644
--- a/arch/sparc/mm/generic_32.c
+++ b/arch/sparc/mm/generic_32.c
@@ -95,3 +95,4 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
flush_tlb_range(vma, beg, end);
return error;
}
+EXPORT_SYMBOL(io_remap_pfn_range);
diff --git a/arch/sparc/mm/generic_64.c b/arch/sparc/mm/generic_64.c
index f362c20..04f2bf4 100644
--- a/arch/sparc/mm/generic_64.c
+++ b/arch/sparc/mm/generic_64.c
@@ -161,3 +161,4 @@ int io_remap_pfn_range(struct vm_area_struct *vma, unsigned long from,
flush_tlb_range(vma, beg, end);
return error;
}
+EXPORT_SYMBOL(io_remap_pfn_range);
diff --git a/arch/sparc/mm/highmem.c b/arch/sparc/mm/highmem.c
index 01fc6c2..752d0c9 100644
--- a/arch/sparc/mm/highmem.c
+++ b/arch/sparc/mm/highmem.c
@@ -62,6 +62,7 @@ void *kmap_atomic(struct page *page, enum km_type type)
return (void*) vaddr;
}
+EXPORT_SYMBOL(kmap_atomic);
void kunmap_atomic(void *kvaddr, enum km_type type)
{
@@ -98,6 +99,7 @@ void kunmap_atomic(void *kvaddr, enum km_type type)
pagefault_enable();
}
+EXPORT_SYMBOL(kunmap_atomic);
/* We may be fed a pagetable here by ptep_to_xxx and others. */
struct page *kmap_atomic_to_page(void *ptr)
diff --git a/arch/sparc/mm/init_32.c b/arch/sparc/mm/init_32.c
index fec9260..cbb282d 100644
--- a/arch/sparc/mm/init_32.c
+++ b/arch/sparc/mm/init_32.c
@@ -38,11 +38,16 @@
DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
unsigned long *sparc_valid_addr_bitmap;
+EXPORT_SYMBOL(sparc_valid_addr_bitmap);
unsigned long phys_base;
+EXPORT_SYMBOL(phys_base);
+
unsigned long pfn_base;
+EXPORT_SYMBOL(pfn_base);
unsigned long page_kernel;
+EXPORT_SYMBOL(page_kernel);
struct sparc_phys_banks sp_banks[SPARC_PHYS_BANKS+1];
unsigned long sparc_unmapped_base;
@@ -522,3 +527,4 @@ void sparc_flush_page_to_ram(struct page *page)
if (vaddr)
__flush_page_to_ram(vaddr);
}
+EXPORT_SYMBOL(sparc_flush_page_to_ram);
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c
index c77c7ef..00373ce 100644
--- a/arch/sparc/mm/init_64.c
+++ b/arch/sparc/mm/init_64.c
@@ -146,6 +146,7 @@ static void __init read_obp_memory(const char *property,
}
unsigned long *sparc64_valid_addr_bitmap __read_mostly;
+EXPORT_SYMBOL(sparc64_valid_addr_bitmap);
/* Kernel physical address base and size in bytes. */
unsigned long kern_base __read_mostly;
@@ -369,6 +370,7 @@ void flush_dcache_page(struct page *page)
out:
put_cpu();
}
+EXPORT_SYMBOL(flush_dcache_page);
void __kprobes flush_icache_range(unsigned long start, unsigned long end)
{
@@ -396,6 +398,7 @@ void __kprobes flush_icache_range(unsigned long start, unsigned long end)
}
}
}
+EXPORT_SYMBOL(flush_icache_range);
void mmu_info(struct seq_file *m)
{
@@ -599,6 +602,7 @@ void __flush_dcache_range(unsigned long start, unsigned long end)
"i" (ASI_DCACHE_INVALIDATE));
}
}
+EXPORT_SYMBOL(__flush_dcache_range);
/* get_new_mmu_context() uses "cache + 1". */
DEFINE_SPINLOCK(ctx_alloc_lock);
diff --git a/arch/sparc/prom/init_32.c b/arch/sparc/prom/init_32.c
index 873217c..6193c33 100644
--- a/arch/sparc/prom/init_32.c
+++ b/arch/sparc/prom/init_32.c
@@ -8,16 +8,20 @@
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/module.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
struct linux_romvec *romvec;
+EXPORT_SYMBOL(romvec);
+
enum prom_major_version prom_vers;
unsigned int prom_rev, prom_prev;
/* The root node of the prom device tree. */
int prom_root_node;
+EXPORT_SYMBOL(prom_root_node);
/* Pointer to the device tree operations structure. */
struct linux_nodeops *prom_nodeops;
diff --git a/arch/sparc/prom/misc_32.c b/arch/sparc/prom/misc_32.c
index cf6c3f6..4d61c54 100644
--- a/arch/sparc/prom/misc_32.c
+++ b/arch/sparc/prom/misc_32.c
@@ -8,6 +8,8 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <linux/module.h>
+
#include <asm/openprom.h>
#include <asm/oplib.h>
#include <asm/auxio.h>
@@ -44,6 +46,7 @@ prom_feval(char *fstring)
restore_current();
spin_unlock_irqrestore(&prom_lock, flags);
}
+EXPORT_SYMBOL(prom_feval);
/* Drop into the prom, with the chance to continue with the 'go'
* prom command.
diff --git a/arch/sparc/prom/misc_64.c b/arch/sparc/prom/misc_64.c
index 9b0c076..eedffb4 100644
--- a/arch/sparc/prom/misc_64.c
+++ b/arch/sparc/prom/misc_64.c
@@ -11,6 +11,8 @@
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
+#include <linux/module.h>
+
#include <asm/openprom.h>
#include <asm/oplib.h>
#include <asm/system.h>
@@ -54,6 +56,7 @@ void prom_feval(const char *fstring)
p1275_cmd("interpret", P1275_ARG(0, P1275_ARG_IN_STRING) |
P1275_INOUT(1, 1), fstring);
}
+EXPORT_SYMBOL(prom_feval);
#ifdef CONFIG_SMP
extern void smp_capture(void);
diff --git a/arch/sparc/prom/ranges.c b/arch/sparc/prom/ranges.c
index 64579a3..cd57908 100644
--- a/arch/sparc/prom/ranges.c
+++ b/arch/sparc/prom/ranges.c
@@ -6,6 +6,8 @@
*/
#include <linux/init.h>
+#include <linux/module.h>
+
#include <asm/openprom.h>
#include <asm/oplib.h>
#include <asm/types.h>
@@ -62,6 +64,7 @@ prom_apply_obio_ranges(struct linux_prom_registers *regs, int nregs)
if(num_obio_ranges)
prom_adjust_regs(regs, nregs, promlib_obio_ranges, num_obio_ranges);
}
+EXPORT_SYMBOL(prom_apply_obio_ranges);
void __init prom_ranges_init(void)
{
diff --git a/arch/sparc/prom/tree_32.c b/arch/sparc/prom/tree_32.c
index 6d81873..646d244 100644
--- a/arch/sparc/prom/tree_32.c
+++ b/arch/sparc/prom/tree_32.c
@@ -5,13 +5,12 @@
* Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
*/
-#define PROMLIB_INTERNAL
-
#include <linux/string.h>
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/ctype.h>
+#include <linux/module.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
@@ -50,6 +49,7 @@ int prom_getchild(int node)
return cnode;
}
+EXPORT_SYMBOL(prom_getchild);
/* Internal version of prom_getsibling that does not alter return values. */
int __prom_getsibling(int node)
@@ -81,6 +81,7 @@ int prom_getsibling(int node)
return sibnode;
}
+EXPORT_SYMBOL(prom_getsibling);
/* Return the length in bytes of property 'prop' at node 'node'.
* Return -1 on error.
@@ -99,6 +100,7 @@ int prom_getproplen(int node, const char *prop)
spin_unlock_irqrestore(&prom_lock, flags);
return ret;
}
+EXPORT_SYMBOL(prom_getproplen);
/* Acquire a property 'prop' at node 'node' and place it in
* 'buffer' which has a size of 'bufsize'. If the acquisition
@@ -119,6 +121,7 @@ int prom_getproperty(int node, const char *prop, char *buffer, int bufsize)
spin_unlock_irqrestore(&prom_lock, flags);
return ret;
}
+EXPORT_SYMBOL(prom_getproperty);
/* Acquire an integer property and return its value. Returns -1
* on failure.
@@ -132,6 +135,7 @@ int prom_getint(int node, char *prop)
return -1;
}
+EXPORT_SYMBOL(prom_getint);
/* Acquire an integer property, upon error return the passed default
* integer.
@@ -145,6 +149,7 @@ int prom_getintdefault(int node, char *property, int deflt)
return retval;
}
+EXPORT_SYMBOL(prom_getintdefault);
/* Acquire a boolean property, 1=TRUE 0=FALSE. */
int prom_getbool(int node, char *prop)
@@ -155,6 +160,7 @@ int prom_getbool(int node, char *prop)
if(retval == -1) return 0;
return 1;
}
+EXPORT_SYMBOL(prom_getbool);
/* Acquire a property whose value is a string, returns a null
* string on error. The char pointer is the user supplied string
@@ -169,6 +175,7 @@ void prom_getstring(int node, char *prop, char *user_buf, int ubuf_size)
user_buf[0] = 0;
return;
}
+EXPORT_SYMBOL(prom_getstring);
/* Does the device at node 'node' have name 'name'?
@@ -204,6 +211,7 @@ int prom_searchsiblings(int node_start, char *nodename)
return 0;
}
+EXPORT_SYMBOL(prom_searchsiblings);
/* Interal version of nextprop that does not alter return values. */
char * __prom_nextprop(int node, char * oprop)
@@ -228,6 +236,7 @@ char * prom_firstprop(int node, char *bufer)
return __prom_nextprop(node, "");
}
+EXPORT_SYMBOL(prom_firstprop);
/* Return the property type string after property type 'oprop'
* at node 'node' . Returns empty string if no more
@@ -240,6 +249,7 @@ char * prom_nextprop(int node, char *oprop, char *buffer)
return __prom_nextprop(node, oprop);
}
+EXPORT_SYMBOL(prom_nextprop);
int prom_finddevice(char *name)
{
@@ -287,6 +297,7 @@ int prom_finddevice(char *name)
}
return node;
}
+EXPORT_SYMBOL(prom_finddevice);
int prom_node_has_property(int node, char *prop)
{
@@ -299,6 +310,7 @@ int prom_node_has_property(int node, char *prop)
} while (*current_property);
return 0;
}
+EXPORT_SYMBOL(prom_node_has_property);
/* Set property 'pname' at node 'node' to value 'value' which has a length
* of 'size' bytes. Return the number of bytes the prom accepted.
@@ -316,6 +328,7 @@ int prom_setprop(int node, const char *pname, char *value, int size)
spin_unlock_irqrestore(&prom_lock, flags);
return ret;
}
+EXPORT_SYMBOL(prom_setprop);
int prom_inst2pkg(int inst)
{
diff --git a/arch/sparc/prom/tree_64.c b/arch/sparc/prom/tree_64.c
index 281aea4..8ea73dd 100644
--- a/arch/sparc/prom/tree_64.c
+++ b/arch/sparc/prom/tree_64.c
@@ -10,6 +10,7 @@
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/sched.h>
+#include <linux/module.h>
#include <asm/openprom.h>
#include <asm/oplib.h>
@@ -32,6 +33,7 @@ inline int prom_getchild(int node)
if(cnode == -1) return 0;
return (int)cnode;
}
+EXPORT_SYMBOL(prom_getchild);
inline int prom_getparent(int node)
{
@@ -63,6 +65,7 @@ inline int prom_getsibling(int node)
return sibnode;
}
+EXPORT_SYMBOL(prom_getsibling);
/* Return the length in bytes of property 'prop' at node 'node'.
* Return -1 on error.
@@ -75,6 +78,7 @@ inline int prom_getproplen(int node, const char *prop)
P1275_INOUT(2, 1),
node, prop);
}
+EXPORT_SYMBOL(prom_getproplen);
/* Acquire a property 'prop' at node 'node' and place it in
* 'buffer' which has a size of 'bufsize'. If the acquisition
@@ -97,6 +101,7 @@ inline int prom_getproperty(int node, const char *prop,
node, prop, buffer, P1275_SIZE(plen));
}
}
+EXPORT_SYMBOL(prom_getproperty);
/* Acquire an integer property and return its value. Returns -1
* on failure.
@@ -110,6 +115,7 @@ inline int prom_getint(int node, const char *prop)
return -1;
}
+EXPORT_SYMBOL(prom_getint);
/* Acquire an integer property, upon error return the passed default
* integer.
@@ -124,6 +130,7 @@ int prom_getintdefault(int node, const char *property, int deflt)
return retval;
}
+EXPORT_SYMBOL(prom_getintdefault);
/* Acquire a boolean property, 1=TRUE 0=FALSE. */
int prom_getbool(int node, const char *prop)
@@ -134,6 +141,7 @@ int prom_getbool(int node, const char *prop)
if(retval == -1) return 0;
return 1;
}
+EXPORT_SYMBOL(prom_getbool);
/* Acquire a property whose value is a string, returns a null
* string on error. The char pointer is the user supplied string
@@ -148,7 +156,7 @@ void prom_getstring(int node, const char *prop, char *user_buf, int ubuf_size)
user_buf[0] = 0;
return;
}
-
+EXPORT_SYMBOL(prom_getstring);
/* Does the device at node 'node' have name 'name'?
* YES = 1 NO = 0
@@ -181,6 +189,7 @@ int prom_searchsiblings(int node_start, const char *nodename)
return 0;
}
+EXPORT_SYMBOL(prom_searchsiblings);
/* Return the first property type for node 'node'.
* buffer should be at least 32B in length
@@ -194,6 +203,7 @@ inline char *prom_firstprop(int node, char *buffer)
node, (char *) 0x0, buffer);
return buffer;
}
+EXPORT_SYMBOL(prom_firstprop);
/* Return the property type string after property type 'oprop'
* at node 'node' . Returns NULL string if no more
@@ -217,6 +227,7 @@ inline char *prom_nextprop(int node, const char *oprop, char *buffer)
node, oprop, buffer);
return buffer;
}
+EXPORT_SYMBOL(prom_nextprop);
int
prom_finddevice(const char *name)
@@ -228,6 +239,7 @@ prom_finddevice(const char *name)
P1275_INOUT(1, 1),
name);
}
+EXPORT_SYMBOL(prom_finddevice);
int prom_node_has_property(int node, const char *prop)
{
@@ -241,7 +253,8 @@ int prom_node_has_property(int node, const char *prop)
} while (*buf);
return 0;
}
-
+EXPORT_SYMBOL(prom_node_has_property);
+
/* Set property 'pname' at node 'node' to value 'value' which has a length
* of 'size' bytes. Return the number of bytes the prom accepted.
*/
@@ -264,6 +277,7 @@ prom_setprop(int node, const char *pname, char *value, int size)
P1275_INOUT(4, 1),
node, pname, value, P1275_SIZE(size));
}
+EXPORT_SYMBOL(prom_setprop);
inline int prom_inst2pkg(int inst)
{
diff --git a/arch/x86/ia32/ia32entry.S b/arch/x86/ia32/ia32entry.S
index 3c14ed0..01e7c4c 100644
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -112,8 +112,8 @@ ENTRY(ia32_sysenter_target)
CFI_DEF_CFA rsp,0
CFI_REGISTER rsp,rbp
SWAPGS_UNSAFE_STACK
- movq %gs:pda_kernelstack, %rsp
- addq $(PDA_STACKOFFSET),%rsp
+ movq PER_CPU_VAR(kernel_stack), %rsp
+ addq $(KERNEL_STACK_OFFSET),%rsp
/*
* No need to follow this irqs on/off section: the syscall
* disabled irqs, here we enable it straight after entry:
@@ -273,13 +273,13 @@ ENDPROC(ia32_sysenter_target)
ENTRY(ia32_cstar_target)
CFI_STARTPROC32 simple
CFI_SIGNAL_FRAME
- CFI_DEF_CFA rsp,PDA_STACKOFFSET
+ CFI_DEF_CFA rsp,KERNEL_STACK_OFFSET
CFI_REGISTER rip,rcx
/*CFI_REGISTER rflags,r11*/
SWAPGS_UNSAFE_STACK
movl %esp,%r8d
CFI_REGISTER rsp,r8
- movq %gs:pda_kernelstack,%rsp
+ movq PER_CPU_VAR(kernel_stack),%rsp
/*
* No need to follow this irqs on/off section: the syscall
* disabled irqs and here we enable it straight after entry:
diff --git a/arch/x86/include/asm/apicnum.h b/arch/x86/include/asm/apicnum.h
new file mode 100644
index 0000000..82f613c
--- /dev/null
+++ b/arch/x86/include/asm/apicnum.h
@@ -0,0 +1,12 @@
+#ifndef _ASM_X86_APICNUM_H
+#define _ASM_X86_APICNUM_H
+
+/* define MAX_IO_APICS */
+#ifdef CONFIG_X86_32
+# define MAX_IO_APICS 64
+#else
+# define MAX_IO_APICS 128
+# define MAX_LOCAL_APIC 32768
+#endif
+
+#endif /* _ASM_X86_APICNUM_H */
diff --git a/arch/x86/include/asm/bitops.h b/arch/x86/include/asm/bitops.h
index e02a359..02b47a6 100644
--- a/arch/x86/include/asm/bitops.h
+++ b/arch/x86/include/asm/bitops.h
@@ -3,6 +3,9 @@
/*
* Copyright 1992, Linus Torvalds.
+ *
+ * Note: inlines with more than a single statement should be marked
+ * __always_inline to avoid problems with older gcc's inlining heuristics.
*/
#ifndef _LINUX_BITOPS_H
@@ -53,7 +56,8 @@
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*/
-static inline void set_bit(unsigned int nr, volatile unsigned long *addr)
+static __always_inline void
+set_bit(unsigned int nr, volatile unsigned long *addr)
{
if (IS_IMMEDIATE(nr)) {
asm volatile(LOCK_PREFIX "orb %1,%0"
@@ -90,7 +94,8 @@ static inline void __set_bit(int nr, volatile unsigned long *addr)
* you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
* in order to ensure changes are visible on other processors.
*/
-static inline void clear_bit(int nr, volatile unsigned long *addr)
+static __always_inline void
+clear_bit(int nr, volatile unsigned long *addr)
{
if (IS_IMMEDIATE(nr)) {
asm volatile(LOCK_PREFIX "andb %1,%0"
@@ -204,7 +209,8 @@ static inline int test_and_set_bit(int nr, volatile unsigned long *addr)
*
* This is the same as test_and_set_bit on x86.
*/
-static inline int test_and_set_bit_lock(int nr, volatile unsigned long *addr)
+static __always_inline int
+test_and_set_bit_lock(int nr, volatile unsigned long *addr)
{
return test_and_set_bit(nr, addr);
}
@@ -300,7 +306,7 @@ static inline int test_and_change_bit(int nr, volatile unsigned long *addr)
return oldbit;
}
-static inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr)
+static __always_inline int constant_test_bit(unsigned int nr, const volatile unsigned long *addr)
{
return ((1UL << (nr % BITS_PER_LONG)) &
(((unsigned long *)addr)[nr / BITS_PER_LONG])) != 0;
diff --git a/arch/x86/include/asm/cpu.h b/arch/x86/include/asm/cpu.h
index bae482d..f03b23e 100644
--- a/arch/x86/include/asm/cpu.h
+++ b/arch/x86/include/asm/cpu.h
@@ -7,6 +7,20 @@
#include <linux/nodemask.h>
#include <linux/percpu.h>
+#ifdef CONFIG_SMP
+
+extern void prefill_possible_map(void);
+
+#else /* CONFIG_SMP */
+
+static inline void prefill_possible_map(void) {}
+
+#define cpu_physical_id(cpu) boot_cpu_physical_apicid
+#define safe_smp_processor_id() 0
+#define stack_smp_processor_id() 0
+
+#endif /* CONFIG_SMP */
+
struct x86_cpu {
struct cpu cpu;
};
@@ -17,4 +31,11 @@ extern void arch_unregister_cpu(int);
#endif
DECLARE_PER_CPU(int, cpu_state);
+
+#ifdef CONFIG_X86_HAS_BOOT_CPU_ID
+extern unsigned char boot_cpu_id;
+#else
+#define boot_cpu_id 0
+#endif
+
#endif /* _ASM_X86_CPU_H */
diff --git a/arch/x86/include/asm/cpumask.h b/arch/x86/include/asm/cpumask.h
new file mode 100644
index 0000000..26c6dad
--- /dev/null
+++ b/arch/x86/include/asm/cpumask.h
@@ -0,0 +1,28 @@
+#ifndef _ASM_X86_CPUMASK_H
+#define _ASM_X86_CPUMASK_H
+#ifndef __ASSEMBLY__
+#include <linux/cpumask.h>
+
+#ifdef CONFIG_X86_64
+
+extern cpumask_var_t cpu_callin_mask;
+extern cpumask_var_t cpu_callout_mask;
+extern cpumask_var_t cpu_initialized_mask;
+extern cpumask_var_t cpu_sibling_setup_mask;
+
+#else /* CONFIG_X86_32 */
+
+extern cpumask_t cpu_callin_map;
+extern cpumask_t cpu_callout_map;
+extern cpumask_t cpu_initialized;
+extern cpumask_t cpu_sibling_setup_map;
+
+#define cpu_callin_mask ((struct cpumask *)&cpu_callin_map)
+#define cpu_callout_mask ((struct cpumask *)&cpu_callout_map)
+#define cpu_initialized_mask ((struct cpumask *)&cpu_initialized)
+#define cpu_sibling_setup_mask ((struct cpumask *)&cpu_sibling_setup_map)
+
+#endif /* CONFIG_X86_32 */
+
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_X86_CPUMASK_H */
diff --git a/arch/x86/include/asm/current.h b/arch/x86/include/asm/current.h
index 0930b4f..c68c361 100644
--- a/arch/x86/include/asm/current.h
+++ b/arch/x86/include/asm/current.h
@@ -1,39 +1,21 @@
#ifndef _ASM_X86_CURRENT_H
#define _ASM_X86_CURRENT_H
-#ifdef CONFIG_X86_32
#include <linux/compiler.h>
#include <asm/percpu.h>
+#ifndef __ASSEMBLY__
struct task_struct;
DECLARE_PER_CPU(struct task_struct *, current_task);
-static __always_inline struct task_struct *get_current(void)
-{
- return x86_read_percpu(current_task);
-}
-
-#else /* X86_32 */
-
-#ifndef __ASSEMBLY__
-#include <asm/pda.h>
-
-struct task_struct;
static __always_inline struct task_struct *get_current(void)
{
- return read_pda(pcurrent);
+ return percpu_read(current_task);
}
-#else /* __ASSEMBLY__ */
-
-#include <asm/asm-offsets.h>
-#define GET_CURRENT(reg) movq %gs:(pda_pcurrent),reg
+#define current get_current()
#endif /* __ASSEMBLY__ */
-#endif /* X86_32 */
-
-#define current get_current()
-
#endif /* _ASM_X86_CURRENT_H */
diff --git a/arch/x86/include/asm/hardirq_32.h b/arch/x86/include/asm/hardirq_32.h
index 7a07897..7838276 100644
--- a/arch/x86/include/asm/hardirq_32.h
+++ b/arch/x86/include/asm/hardirq_32.h
@@ -20,6 +20,9 @@ typedef struct {
DECLARE_PER_CPU(irq_cpustat_t, irq_stat);
+/* We can have at most NR_VECTORS irqs routed to a cpu at a time */
+#define MAX_HARDIRQS_PER_CPU NR_VECTORS
+
#define __ARCH_IRQ_STAT
#define __IRQ_STAT(cpu, member) (per_cpu(irq_stat, cpu).member)
diff --git a/arch/x86/include/asm/hardirq_64.h b/arch/x86/include/asm/hardirq_64.h
index b5a6b5d..42930b2 100644
--- a/arch/x86/include/asm/hardirq_64.h
+++ b/arch/x86/include/asm/hardirq_64.h
@@ -3,22 +3,37 @@
#include <linux/threads.h>
#include <linux/irq.h>
-#include <asm/pda.h>
#include <asm/apic.h>
+typedef struct {
+ unsigned int __softirq_pending;
+ unsigned int __nmi_count; /* arch dependent */
+ unsigned int apic_timer_irqs; /* arch dependent */
+ unsigned int apic_perf_irqs; /* arch dependent */
+ unsigned int irq0_irqs;
+ unsigned int irq_resched_count;
+ unsigned int irq_call_count;
+ unsigned int irq_tlb_count;
+ unsigned int irq_thermal_count;
+ unsigned int irq_spurious_count;
+ unsigned int irq_threshold_count;
+} ____cacheline_aligned irq_cpustat_t;
+
+DECLARE_PER_CPU(irq_cpustat_t, irq_stat);
+
/* We can have at most NR_VECTORS irqs routed to a cpu at a time */
#define MAX_HARDIRQS_PER_CPU NR_VECTORS
#define __ARCH_IRQ_STAT 1
-#define inc_irq_stat(member) add_pda(member, 1)
+#define inc_irq_stat(member) percpu_add(irq_stat.member, 1)
-#define local_softirq_pending() read_pda(__softirq_pending)
+#define local_softirq_pending() percpu_read(irq_stat.__softirq_pending)
#define __ARCH_SET_SOFTIRQ_PENDING 1
-#define set_softirq_pending(x) write_pda(__softirq_pending, (x))
-#define or_softirq_pending(x) or_pda(__softirq_pending, (x))
+#define set_softirq_pending(x) percpu_write(irq_stat.__softirq_pending, (x))
+#define or_softirq_pending(x) percpu_or(irq_stat.__softirq_pending, (x))
extern void ack_bad_irq(unsigned int irq);
diff --git a/arch/x86/include/asm/io_apic.h b/arch/x86/include/asm/io_apic.h
index 7a1f44a..08ec793 100644
--- a/arch/x86/include/asm/io_apic.h
+++ b/arch/x86/include/asm/io_apic.h
@@ -114,38 +114,16 @@ struct IR_IO_APIC_route_entry {
extern int nr_ioapics;
extern int nr_ioapic_registers[MAX_IO_APICS];
-/*
- * MP-BIOS irq configuration table structures:
- */
-
#define MP_MAX_IOAPIC_PIN 127
-struct mp_config_ioapic {
- unsigned long mp_apicaddr;
- unsigned int mp_apicid;
- unsigned char mp_type;
- unsigned char mp_apicver;
- unsigned char mp_flags;
-};
-
-struct mp_config_intsrc {
- unsigned int mp_dstapic;
- unsigned char mp_type;
- unsigned char mp_irqtype;
- unsigned short mp_irqflag;
- unsigned char mp_srcbus;
- unsigned char mp_srcbusirq;
- unsigned char mp_dstirq;
-};
-
/* I/O APIC entries */
-extern struct mp_config_ioapic mp_ioapics[MAX_IO_APICS];
+extern struct mpc_ioapic mp_ioapics[MAX_IO_APICS];
/* # of MP IRQ source entries */
extern int mp_irq_entries;
/* MP IRQ source entries */
-extern struct mp_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
+extern struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
/* non-0 if default (table-less) MP configuration */
extern int mpc_default_type;
diff --git a/arch/x86/include/asm/irq_regs_32.h b/arch/x86/include/asm/irq_regs_32.h
index 86afd74..d7ed33ee 100644
--- a/arch/x86/include/asm/irq_regs_32.h
+++ b/arch/x86/include/asm/irq_regs_32.h
@@ -15,7 +15,7 @@ DECLARE_PER_CPU(struct pt_regs *, irq_regs);
static inline struct pt_regs *get_irq_regs(void)
{
- return x86_read_percpu(irq_regs);
+ return percpu_read(irq_regs);
}
static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs)
@@ -23,7 +23,7 @@ static inline struct pt_regs *set_irq_regs(struct pt_regs *new_regs)
struct pt_regs *old_regs;
old_regs = get_irq_regs();
- x86_write_percpu(irq_regs, new_regs);
+ percpu_write(irq_regs, new_regs);
return old_regs;
}
diff --git a/arch/x86/include/asm/irq_vectors.h b/arch/x86/include/asm/irq_vectors.h
index 21a0b92..1554d02 100644
--- a/arch/x86/include/asm/irq_vectors.h
+++ b/arch/x86/include/asm/irq_vectors.h
@@ -110,6 +110,8 @@
#if defined(CONFIG_X86_IO_APIC) && !defined(CONFIG_X86_VOYAGER)
+#include <asm/apicnum.h> /* need MAX_IO_APICS */
+
#ifndef CONFIG_SPARSE_IRQ
# if NR_CPUS < MAX_IO_APICS
# define NR_IRQS (NR_VECTORS + (32 * NR_CPUS))
@@ -117,11 +119,12 @@
# define NR_IRQS (NR_VECTORS + (32 * MAX_IO_APICS))
# endif
#else
-# if (8 * NR_CPUS) > (32 * MAX_IO_APICS)
-# define NR_IRQS (NR_VECTORS + (8 * NR_CPUS))
-# else
-# define NR_IRQS (NR_VECTORS + (32 * MAX_IO_APICS))
-# endif
+
+# define NR_IRQS \
+ ((8 * NR_CPUS) > (32 * MAX_IO_APICS) ? \
+ (NR_VECTORS + (8 * NR_CPUS)) : \
+ (NR_VECTORS + (32 * MAX_IO_APICS))) \
+
#endif
#elif defined(CONFIG_X86_VOYAGER)
diff --git a/arch/x86/include/asm/mach-default/mach_wakecpu.h b/arch/x86/include/asm/mach-default/mach_wakecpu.h
index ceb0136..89897a6 100644
--- a/arch/x86/include/asm/mach-default/mach_wakecpu.h
+++ b/arch/x86/include/asm/mach-default/mach_wakecpu.h
@@ -24,7 +24,13 @@ static inline void restore_NMI_vector(unsigned short *high, unsigned short *low)
{
}
+#ifdef CONFIG_SMP
extern void __inquire_remote_apic(int apicid);
+#else /* CONFIG_SMP */
+static inline void __inquire_remote_apic(int apicid)
+{
+}
+#endif /* CONFIG_SMP */
static inline void inquire_remote_apic(int apicid)
{
diff --git a/arch/x86/include/asm/mmu_context_32.h b/arch/x86/include/asm/mmu_context_32.h
index 7e98ce1..08b5345 100644
--- a/arch/x86/include/asm/mmu_context_32.h
+++ b/arch/x86/include/asm/mmu_context_32.h
@@ -4,8 +4,8 @@
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
{
#ifdef CONFIG_SMP
- if (x86_read_percpu(cpu_tlbstate.state) == TLBSTATE_OK)
- x86_write_percpu(cpu_tlbstate.state, TLBSTATE_LAZY);
+ if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
+ percpu_write(cpu_tlbstate.state, TLBSTATE_LAZY);
#endif
}
@@ -19,8 +19,8 @@ static inline void switch_mm(struct mm_struct *prev,
/* stop flush ipis for the previous mm */
cpu_clear(cpu, prev->cpu_vm_mask);
#ifdef CONFIG_SMP
- x86_write_percpu(cpu_tlbstate.state, TLBSTATE_OK);
- x86_write_percpu(cpu_tlbstate.active_mm, next);
+ percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
+ percpu_write(cpu_tlbstate.active_mm, next);
#endif
cpu_set(cpu, next->cpu_vm_mask);
@@ -35,8 +35,8 @@ static inline void switch_mm(struct mm_struct *prev,
}
#ifdef CONFIG_SMP
else {
- x86_write_percpu(cpu_tlbstate.state, TLBSTATE_OK);
- BUG_ON(x86_read_percpu(cpu_tlbstate.active_mm) != next);
+ percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
+ BUG_ON(percpu_read(cpu_tlbstate.active_mm) != next);
if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
/* We were in lazy tlb mode and leave_mm disabled
diff --git a/arch/x86/include/asm/mmu_context_64.h b/arch/x86/include/asm/mmu_context_64.h
index 677d36e..c457250 100644
--- a/arch/x86/include/asm/mmu_context_64.h
+++ b/arch/x86/include/asm/mmu_context_64.h
@@ -1,13 +1,11 @@
#ifndef _ASM_X86_MMU_CONTEXT_64_H
#define _ASM_X86_MMU_CONTEXT_64_H
-#include <asm/pda.h>
-
static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
{
#ifdef CONFIG_SMP
- if (read_pda(mmu_state) == TLBSTATE_OK)
- write_pda(mmu_state, TLBSTATE_LAZY);
+ if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
+ percpu_write(cpu_tlbstate.state, TLBSTATE_LAZY);
#endif
}
@@ -19,8 +17,8 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
/* stop flush ipis for the previous mm */
cpu_clear(cpu, prev->cpu_vm_mask);
#ifdef CONFIG_SMP
- write_pda(mmu_state, TLBSTATE_OK);
- write_pda(active_mm, next);
+ percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
+ percpu_write(cpu_tlbstate.active_mm, next);
#endif
cpu_set(cpu, next->cpu_vm_mask);
load_cr3(next->pgd);
@@ -30,9 +28,9 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
}
#ifdef CONFIG_SMP
else {
- write_pda(mmu_state, TLBSTATE_OK);
- if (read_pda(active_mm) != next)
- BUG();
+ percpu_write(cpu_tlbstate.state, TLBSTATE_OK);
+ BUG_ON(percpu_read(cpu_tlbstate.active_mm) != next);
+
if (!cpu_test_and_set(cpu, next->cpu_vm_mask)) {
/* We were in lazy tlb mode and leave_mm disabled
* tlb flush IPI delivery. We must reload CR3
diff --git a/arch/x86/include/asm/mpspec_def.h b/arch/x86/include/asm/mpspec_def.h
index 59568bc..4a7f96d 100644
--- a/arch/x86/include/asm/mpspec_def.h
+++ b/arch/x86/include/asm/mpspec_def.h
@@ -24,17 +24,18 @@
# endif
#endif
-struct intel_mp_floating {
- char mpf_signature[4]; /* "_MP_" */
- unsigned int mpf_physptr; /* Configuration table address */
- unsigned char mpf_length; /* Our length (paragraphs) */
- unsigned char mpf_specification;/* Specification version */
- unsigned char mpf_checksum; /* Checksum (makes sum 0) */
- unsigned char mpf_feature1; /* Standard or configuration ? */
- unsigned char mpf_feature2; /* Bit7 set for IMCR|PIC */
- unsigned char mpf_feature3; /* Unused (0) */
- unsigned char mpf_feature4; /* Unused (0) */
- unsigned char mpf_feature5; /* Unused (0) */
+/* Intel MP Floating Pointer Structure */
+struct mpf_intel {
+ char signature[4]; /* "_MP_" */
+ unsigned int physptr; /* Configuration table address */
+ unsigned char length; /* Our length (paragraphs) */
+ unsigned char specification; /* Specification version */
+ unsigned char checksum; /* Checksum (makes sum 0) */
+ unsigned char feature1; /* Standard or configuration ? */
+ unsigned char feature2; /* Bit7 set for IMCR|PIC */
+ unsigned char feature3; /* Unused (0) */
+ unsigned char feature4; /* Unused (0) */
+ unsigned char feature5; /* Unused (0) */
};
#define MPC_SIGNATURE "PCMP"
diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
index cb988aa..14080d2 100644
--- a/arch/x86/include/asm/mtrr.h
+++ b/arch/x86/include/asm/mtrr.h
@@ -58,15 +58,15 @@ struct mtrr_gentry {
#endif /* !__i386__ */
struct mtrr_var_range {
- u32 base_lo;
- u32 base_hi;
- u32 mask_lo;
- u32 mask_hi;
+ __u32 base_lo;
+ __u32 base_hi;
+ __u32 mask_lo;
+ __u32 mask_hi;
};
/* In the Intel processor's MTRR interface, the MTRR type is always held in
an 8 bit field: */
-typedef u8 mtrr_type;
+typedef __u8 mtrr_type;
#define MTRR_NUM_FIXED_RANGES 88
#define MTRR_MAX_VAR_RANGES 256
diff --git a/arch/x86/include/asm/page_64.h b/arch/x86/include/asm/page_64.h
index 5ebca29..e27fdbe 100644
--- a/arch/x86/include/asm/page_64.h
+++ b/arch/x86/include/asm/page_64.h
@@ -13,8 +13,8 @@
#define DEBUG_STACK_ORDER (EXCEPTION_STACK_ORDER + 1)
#define DEBUG_STKSZ (PAGE_SIZE << DEBUG_STACK_ORDER)
-#define IRQSTACK_ORDER 2
-#define IRQSTACKSIZE (PAGE_SIZE << IRQSTACK_ORDER)
+#define IRQ_STACK_ORDER 2
+#define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER)
#define STACKFAULT_STACK 1
#define DOUBLEFAULT_STACK 2
diff --git a/arch/x86/include/asm/paravirt.h b/arch/x86/include/asm/paravirt.h
index ba3e2ff..c26c6bf 100644
--- a/arch/x86/include/asm/paravirt.h
+++ b/arch/x86/include/asm/paravirt.h
@@ -244,7 +244,8 @@ struct pv_mmu_ops {
void (*flush_tlb_user)(void);
void (*flush_tlb_kernel)(void);
void (*flush_tlb_single)(unsigned long addr);
- void (*flush_tlb_others)(const cpumask_t *cpus, struct mm_struct *mm,
+ void (*flush_tlb_others)(const struct cpumask *cpus,
+ struct mm_struct *mm,
unsigned long va);
/* Hooks for allocating and freeing a pagetable top-level */
@@ -984,10 +985,11 @@ static inline void __flush_tlb_single(unsigned long addr)
PVOP_VCALL1(pv_mmu_ops.flush_tlb_single, addr);
}
-static inline void flush_tlb_others(cpumask_t cpumask, struct mm_struct *mm,
+static inline void flush_tlb_others(const struct cpumask *cpumask,
+ struct mm_struct *mm,
unsigned long va)
{
- PVOP_VCALL3(pv_mmu_ops.flush_tlb_others, &cpumask, mm, va);
+ PVOP_VCALL3(pv_mmu_ops.flush_tlb_others, cpumask, mm, va);
}
static inline int paravirt_pgd_alloc(struct mm_struct *mm)
diff --git a/arch/x86/include/asm/pda.h b/arch/x86/include/asm/pda.h
index 90a8d9d..c31ca04 100644
--- a/arch/x86/include/asm/pda.h
+++ b/arch/x86/include/asm/pda.h
@@ -5,134 +5,41 @@
#include <linux/stddef.h>
#include <linux/types.h>
#include <linux/cache.h>
+#include <linux/threads.h>
#include <asm/page.h>
+#include <asm/percpu.h>
/* Per processor datastructure. %gs points to it while the kernel runs */
struct x8664_pda {
- struct task_struct *pcurrent; /* 0 Current process */
- unsigned long data_offset; /* 8 Per cpu data offset from linker
- address */
- unsigned long kernelstack; /* 16 top of kernel stack for current */
- unsigned long oldrsp; /* 24 user rsp for system call */
- int irqcount; /* 32 Irq nesting counter. Starts -1 */
- unsigned int cpunumber; /* 36 Logical CPU number */
+ unsigned long unused1;
+ unsigned long unused2;
+ unsigned long unused3;
+ unsigned long unused4;
+ int unused5;
+ unsigned int unused6; /* 36 was cpunumber */
#ifdef CONFIG_CC_STACKPROTECTOR
unsigned long stack_canary; /* 40 stack canary value */
/* gcc-ABI: this canary MUST be at
offset 40!!! */
#endif
- char *irqstackptr;
- short nodenumber; /* number of current node (32k max) */
short in_bootmem; /* pda lives in bootmem */
- unsigned int __softirq_pending;
- unsigned int __nmi_count; /* number of NMI on this CPUs */
- short mmu_state;
- short isidle;
- struct mm_struct *active_mm;
- unsigned apic_timer_irqs;
- unsigned apic_perf_irqs;
- unsigned irq0_irqs;
- unsigned irq_resched_count;
- unsigned irq_call_count;
- unsigned irq_tlb_count;
- unsigned irq_thermal_count;
- unsigned irq_threshold_count;
- unsigned irq_spurious_count;
} ____cacheline_aligned_in_smp;
-extern struct x8664_pda **_cpu_pda;
+DECLARE_PER_CPU(struct x8664_pda, __pda);
extern void pda_init(int);
-#define cpu_pda(i) (_cpu_pda[i])
+#define cpu_pda(cpu) (&per_cpu(__pda, cpu))
-/*
- * There is no fast way to get the base address of the PDA, all the accesses
- * have to mention %fs/%gs. So it needs to be done this Torvaldian way.
- */
-extern void __bad_pda_field(void) __attribute__((noreturn));
-
-/*
- * proxy_pda doesn't actually exist, but tell gcc it is accessed for
- * all PDA accesses so it gets read/write dependencies right.
- */
-extern struct x8664_pda _proxy_pda;
-
-#define pda_offset(field) offsetof(struct x8664_pda, field)
-
-#define pda_to_op(op, field, val) \
-do { \
- typedef typeof(_proxy_pda.field) T__; \
- if (0) { T__ tmp__; tmp__ = (val); } /* type checking */ \
- switch (sizeof(_proxy_pda.field)) { \
- case 2: \
- asm(op "w %1,%%gs:%c2" : \
- "+m" (_proxy_pda.field) : \
- "ri" ((T__)val), \
- "i"(pda_offset(field))); \
- break; \
- case 4: \
- asm(op "l %1,%%gs:%c2" : \
- "+m" (_proxy_pda.field) : \
- "ri" ((T__)val), \
- "i" (pda_offset(field))); \
- break; \
- case 8: \
- asm(op "q %1,%%gs:%c2": \
- "+m" (_proxy_pda.field) : \
- "ri" ((T__)val), \
- "i"(pda_offset(field))); \
- break; \
- default: \
- __bad_pda_field(); \
- } \
-} while (0)
-
-#define pda_from_op(op, field) \
-({ \
- typeof(_proxy_pda.field) ret__; \
- switch (sizeof(_proxy_pda.field)) { \
- case 2: \
- asm(op "w %%gs:%c1,%0" : \
- "=r" (ret__) : \
- "i" (pda_offset(field)), \
- "m" (_proxy_pda.field)); \
- break; \
- case 4: \
- asm(op "l %%gs:%c1,%0": \
- "=r" (ret__): \
- "i" (pda_offset(field)), \
- "m" (_proxy_pda.field)); \
- break; \
- case 8: \
- asm(op "q %%gs:%c1,%0": \
- "=r" (ret__) : \
- "i" (pda_offset(field)), \
- "m" (_proxy_pda.field)); \
- break; \
- default: \
- __bad_pda_field(); \
- } \
- ret__; \
-})
-
-#define read_pda(field) pda_from_op("mov", field)
-#define write_pda(field, val) pda_to_op("mov", field, val)
-#define add_pda(field, val) pda_to_op("add", field, val)
-#define sub_pda(field, val) pda_to_op("sub", field, val)
-#define or_pda(field, val) pda_to_op("or", field, val)
+#define read_pda(field) percpu_read(__pda.field)
+#define write_pda(field, val) percpu_write(__pda.field, val)
+#define add_pda(field, val) percpu_add(__pda.field, val)
+#define sub_pda(field, val) percpu_sub(__pda.field, val)
+#define or_pda(field, val) percpu_or(__pda.field, val)
/* This is not atomic against other CPUs -- CPU preemption needs to be off */
#define test_and_clear_bit_pda(bit, field) \
-({ \
- int old__; \
- asm volatile("btr %2,%%gs:%c3\n\tsbbl %0,%0" \
- : "=r" (old__), "+m" (_proxy_pda.field) \
- : "dIr" (bit), "i" (pda_offset(field)) : "memory");\
- old__; \
-})
+ x86_test_and_clear_bit_percpu(bit, __pda.field)
#endif
-#define PDA_STACKOFFSET (5*8)
-
#endif /* _ASM_X86_PDA_H */
diff --git a/arch/x86/include/asm/percpu.h b/arch/x86/include/asm/percpu.h
index ece7205..165d527 100644
--- a/arch/x86/include/asm/percpu.h
+++ b/arch/x86/include/asm/percpu.h
@@ -2,53 +2,12 @@
#define _ASM_X86_PERCPU_H
#ifdef CONFIG_X86_64
-#include <linux/compiler.h>
-
-/* Same as asm-generic/percpu.h, except that we store the per cpu offset
- in the PDA. Longer term the PDA and every per cpu variable
- should be just put into a single section and referenced directly
- from %gs */
-
-#ifdef CONFIG_SMP
-#include <asm/pda.h>
-
-#define __per_cpu_offset(cpu) (cpu_pda(cpu)->data_offset)
-#define __my_cpu_offset read_pda(data_offset)
-
-#define per_cpu_offset(x) (__per_cpu_offset(x))
-
+#define __percpu_seg gs
+#define __percpu_mov_op movq
+#else
+#define __percpu_seg fs
+#define __percpu_mov_op movl
#endif
-#include <asm-generic/percpu.h>
-
-DECLARE_PER_CPU(struct x8664_pda, pda);
-
-/*
- * These are supposed to be implemented as a single instruction which
- * operates on the per-cpu data base segment. x86-64 doesn't have
- * that yet, so this is a fairly inefficient workaround for the
- * meantime. The single instruction is atomic with respect to
- * preemption and interrupts, so we need to explicitly disable
- * interrupts here to achieve the same effect. However, because it
- * can be used from within interrupt-disable/enable, we can't actually
- * disable interrupts; disabling preemption is enough.
- */
-#define x86_read_percpu(var) \
- ({ \
- typeof(per_cpu_var(var)) __tmp; \
- preempt_disable(); \
- __tmp = __get_cpu_var(var); \
- preempt_enable(); \
- __tmp; \
- })
-
-#define x86_write_percpu(var, val) \
- do { \
- preempt_disable(); \
- __get_cpu_var(var) = (val); \
- preempt_enable(); \
- } while(0)
-
-#else /* CONFIG_X86_64 */
#ifdef __ASSEMBLY__
@@ -65,47 +24,26 @@ DECLARE_PER_CPU(struct x8664_pda, pda);
* PER_CPU(cpu_gdt_descr, %ebx)
*/
#ifdef CONFIG_SMP
-#define PER_CPU(var, reg) \
- movl %fs:per_cpu__##this_cpu_off, reg; \
+#define PER_CPU(var, reg) \
+ __percpu_mov_op %__percpu_seg:per_cpu__this_cpu_off, reg; \
lea per_cpu__##var(reg), reg
-#define PER_CPU_VAR(var) %fs:per_cpu__##var
+#define PER_CPU_VAR(var) %__percpu_seg:per_cpu__##var
#else /* ! SMP */
-#define PER_CPU(var, reg) \
- movl $per_cpu__##var, reg
+#define PER_CPU(var, reg) \
+ __percpu_mov_op $per_cpu__##var, reg
#define PER_CPU_VAR(var) per_cpu__##var
#endif /* SMP */
#else /* ...!ASSEMBLY */
-/*
- * PER_CPU finds an address of a per-cpu variable.
- *
- * Args:
- * var - variable name
- * cpu - 32bit register containing the current CPU number
- *
- * The resulting address is stored in the "cpu" argument.
- *
- * Example:
- * PER_CPU(cpu_gdt_descr, %ebx)
- */
-#ifdef CONFIG_SMP
-
-#define __my_cpu_offset x86_read_percpu(this_cpu_off)
-
-/* fs segment starts at (positive) offset == __per_cpu_offset[cpu] */
-#define __percpu_seg "%%fs:"
-
-#else /* !SMP */
+#include <linux/stringify.h>
-#define __percpu_seg ""
-
-#endif /* SMP */
-
-#include <asm-generic/percpu.h>
-
-/* We can use this directly for local CPU (faster). */
-DECLARE_PER_CPU(unsigned long, this_cpu_off);
+#ifdef CONFIG_SMP
+#define __percpu_arg(x) "%%"__stringify(__percpu_seg)":%P" #x
+#define __my_cpu_offset percpu_read(this_cpu_off)
+#else
+#define __percpu_arg(x) "%" #x
+#endif
/* For arch-specific code, we can use direct single-insn ops (they
* don't give an lvalue though). */
@@ -120,20 +58,25 @@ do { \
} \
switch (sizeof(var)) { \
case 1: \
- asm(op "b %1,"__percpu_seg"%0" \
+ asm(op "b %1,"__percpu_arg(0) \
: "+m" (var) \
: "ri" ((T__)val)); \
break; \
case 2: \
- asm(op "w %1,"__percpu_seg"%0" \
+ asm(op "w %1,"__percpu_arg(0) \
: "+m" (var) \
: "ri" ((T__)val)); \
break; \
case 4: \
- asm(op "l %1,"__percpu_seg"%0" \
+ asm(op "l %1,"__percpu_arg(0) \
: "+m" (var) \
: "ri" ((T__)val)); \
break; \
+ case 8: \
+ asm(op "q %1,"__percpu_arg(0) \
+ : "+m" (var) \
+ : "r" ((T__)val)); \
+ break; \
default: __bad_percpu_size(); \
} \
} while (0)
@@ -143,17 +86,22 @@ do { \
typeof(var) ret__; \
switch (sizeof(var)) { \
case 1: \
- asm(op "b "__percpu_seg"%1,%0" \
+ asm(op "b "__percpu_arg(1)",%0" \
: "=r" (ret__) \
: "m" (var)); \
break; \
case 2: \
- asm(op "w "__percpu_seg"%1,%0" \
+ asm(op "w "__percpu_arg(1)",%0" \
: "=r" (ret__) \
: "m" (var)); \
break; \
case 4: \
- asm(op "l "__percpu_seg"%1,%0" \
+ asm(op "l "__percpu_arg(1)",%0" \
+ : "=r" (ret__) \
+ : "m" (var)); \
+ break; \
+ case 8: \
+ asm(op "q "__percpu_arg(1)",%0" \
: "=r" (ret__) \
: "m" (var)); \
break; \
@@ -162,13 +110,36 @@ do { \
ret__; \
})
-#define x86_read_percpu(var) percpu_from_op("mov", per_cpu__##var)
-#define x86_write_percpu(var, val) percpu_to_op("mov", per_cpu__##var, val)
-#define x86_add_percpu(var, val) percpu_to_op("add", per_cpu__##var, val)
-#define x86_sub_percpu(var, val) percpu_to_op("sub", per_cpu__##var, val)
-#define x86_or_percpu(var, val) percpu_to_op("or", per_cpu__##var, val)
+#define percpu_read(var) percpu_from_op("mov", per_cpu__##var)
+#define percpu_write(var, val) percpu_to_op("mov", per_cpu__##var, val)
+#define percpu_add(var, val) percpu_to_op("add", per_cpu__##var, val)
+#define percpu_sub(var, val) percpu_to_op("sub", per_cpu__##var, val)
+#define percpu_and(var, val) percpu_to_op("and", per_cpu__##var, val)
+#define percpu_or(var, val) percpu_to_op("or", per_cpu__##var, val)
+#define percpu_xor(var, val) percpu_to_op("xor", per_cpu__##var, val)
+
+/* This is not atomic against other CPUs -- CPU preemption needs to be off */
+#define x86_test_and_clear_bit_percpu(bit, var) \
+({ \
+ int old__; \
+ asm volatile("btr %2,"__percpu_arg(1)"\n\tsbbl %0,%0" \
+ : "=r" (old__), "+m" (per_cpu__##var) \
+ : "dIr" (bit)); \
+ old__; \
+})
+
+#include <asm-generic/percpu.h>
+
+/* We can use this directly for local CPU (faster). */
+DECLARE_PER_CPU(unsigned long, this_cpu_off);
+
+#ifdef CONFIG_X86_64
+extern void load_pda_offset(int cpu);
+#else
+static inline void load_pda_offset(int cpu) { }
+#endif
+
#endif /* !__ASSEMBLY__ */
-#endif /* !CONFIG_X86_64 */
#ifdef CONFIG_SMP
@@ -195,9 +166,9 @@ do { \
#define early_per_cpu_ptr(_name) (_name##_early_ptr)
#define early_per_cpu_map(_name, _idx) (_name##_early_map[_idx])
#define early_per_cpu(_name, _cpu) \
- (early_per_cpu_ptr(_name) ? \
- early_per_cpu_ptr(_name)[_cpu] : \
- per_cpu(_name, _cpu))
+ *(early_per_cpu_ptr(_name) ? \
+ &early_per_cpu_ptr(_name)[_cpu] : \
+ &per_cpu(_name, _cpu))
#else /* !CONFIG_SMP */
#define DEFINE_EARLY_PER_CPU(_type, _name, _initvalue) \
diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h
index 83e69f4..06bbcbd 100644
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -341,6 +341,25 @@ static inline pgprot_t pgprot_modify(pgprot_t oldprot, pgprot_t newprot)
#define canon_pgprot(p) __pgprot(pgprot_val(p) & __supported_pte_mask)
+static inline int is_new_memtype_allowed(unsigned long flags,
+ unsigned long new_flags)
+{
+ /*
+ * Certain new memtypes are not allowed with certain
+ * requested memtype:
+ * - request is uncached, return cannot be write-back
+ * - request is write-combine, return cannot be write-back
+ */
+ if ((flags == _PAGE_CACHE_UC_MINUS &&
+ new_flags == _PAGE_CACHE_WB) ||
+ (flags == _PAGE_CACHE_WC &&
+ new_flags == _PAGE_CACHE_WB)) {
+ return 0;
+ }
+
+ return 1;
+}
+
#ifndef __ASSEMBLY__
/* Indicate that x86 has its own track and untrack pfn vma functions */
#define __HAVE_PFNMAP_TRACKING
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 091cd88..f511246 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -378,6 +378,9 @@ union thread_xstate {
#ifdef CONFIG_X86_64
DECLARE_PER_CPU(struct orig_ist, orig_ist);
+
+DECLARE_PER_CPU(char[IRQ_STACK_SIZE], irq_stack);
+DECLARE_PER_CPU(char *, irq_stack_ptr);
#endif
extern void print_cpu_info(struct cpuinfo_x86 *);
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
index ebe858c..5369497 100644
--- a/arch/x86/include/asm/setup.h
+++ b/arch/x86/include/asm/setup.h
@@ -100,7 +100,6 @@ extern unsigned long init_pg_tables_start;
extern unsigned long init_pg_tables_end;
#else
-void __init x86_64_init_pda(void);
void __init x86_64_start_kernel(char *real_mode);
void __init x86_64_start_reservations(char *real_mode_data);
diff --git a/arch/x86/include/asm/smp.h b/arch/x86/include/asm/smp.h
index 19953df..68636e7 100644
--- a/arch/x86/include/asm/smp.h
+++ b/arch/x86/include/asm/smp.h
@@ -17,32 +17,7 @@
#endif
#include <asm/pda.h>
#include <asm/thread_info.h>
-
-#ifdef CONFIG_X86_64
-
-extern cpumask_var_t cpu_callin_mask;
-extern cpumask_var_t cpu_callout_mask;
-extern cpumask_var_t cpu_initialized_mask;
-extern cpumask_var_t cpu_sibling_setup_mask;
-
-#else /* CONFIG_X86_32 */
-
-extern cpumask_t cpu_callin_map;
-extern cpumask_t cpu_callout_map;
-extern cpumask_t cpu_initialized;
-extern cpumask_t cpu_sibling_setup_map;
-
-#define cpu_callin_mask ((struct cpumask *)&cpu_callin_map)
-#define cpu_callout_mask ((struct cpumask *)&cpu_callout_map)
-#define cpu_initialized_mask ((struct cpumask *)&cpu_initialized)
-#define cpu_sibling_setup_mask ((struct cpumask *)&cpu_sibling_setup_map)
-
-#endif /* CONFIG_X86_32 */
-
-extern void (*mtrr_hook)(void);
-extern void zap_low_mappings(void);
-
-extern int __cpuinit get_local_pda(int cpu);
+#include <asm/cpumask.h>
extern int smp_num_siblings;
extern unsigned int num_processors;
@@ -50,9 +25,7 @@ extern unsigned int num_processors;
DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
DECLARE_PER_CPU(cpumask_t, cpu_core_map);
DECLARE_PER_CPU(u16, cpu_llc_id);
-#ifdef CONFIG_X86_32
DECLARE_PER_CPU(int, cpu_number);
-#endif
static inline struct cpumask *cpu_sibling_mask(int cpu)
{
@@ -167,8 +140,6 @@ void play_dead_common(void);
void native_send_call_func_ipi(const struct cpumask *mask);
void native_send_call_func_single_ipi(int cpu);
-extern void prefill_possible_map(void);
-
void smp_store_cpu_info(int id);
#define cpu_physical_id(cpu) per_cpu(x86_cpu_to_apicid, cpu)
@@ -177,10 +148,6 @@ static inline int num_booting_cpus(void)
{
return cpumask_weight(cpu_callout_mask);
}
-#else
-static inline void prefill_possible_map(void)
-{
-}
#endif /* CONFIG_SMP */
extern unsigned disabled_cpus __cpuinitdata;
@@ -191,11 +158,11 @@ extern unsigned disabled_cpus __cpuinitdata;
* from the initial startup. We map APIC_BASE very early in page_setup(),
* so this is correct in the x86 case.
*/
-#define raw_smp_processor_id() (x86_read_percpu(cpu_number))
+#define raw_smp_processor_id() (percpu_read(cpu_number))
extern int safe_smp_processor_id(void);
#elif defined(CONFIG_X86_64_SMP)
-#define raw_smp_processor_id() read_pda(cpunumber)
+#define raw_smp_processor_id() (percpu_read(cpu_number))
#define stack_smp_processor_id() \
({ \
@@ -205,10 +172,6 @@ extern int safe_smp_processor_id(void);
})
#define safe_smp_processor_id() smp_processor_id()
-#else /* !CONFIG_X86_32_SMP && !CONFIG_X86_64_SMP */
-#define cpu_physical_id(cpu) boot_cpu_physical_apicid
-#define safe_smp_processor_id() 0
-#define stack_smp_processor_id() 0
#endif
#ifdef CONFIG_X86_LOCAL_APIC
@@ -251,11 +214,5 @@ static inline int hard_smp_processor_id(void)
#endif /* CONFIG_X86_LOCAL_APIC */
-#ifdef CONFIG_X86_HAS_BOOT_CPU_ID
-extern unsigned char boot_cpu_id;
-#else
-#define boot_cpu_id 0
-#endif
-
#endif /* __ASSEMBLY__ */
#endif /* _ASM_X86_SMP_H */
diff --git a/arch/x86/include/asm/system.h b/arch/x86/include/asm/system.h
index 8e626ea..d1dc27d 100644
--- a/arch/x86/include/asm/system.h
+++ b/arch/x86/include/asm/system.h
@@ -94,7 +94,7 @@ do { \
"call __switch_to\n\t" \
".globl thread_return\n" \
"thread_return:\n\t" \
- "movq %%gs:%P[pda_pcurrent],%%rsi\n\t" \
+ "movq "__percpu_arg([current_task])",%%rsi\n\t" \
"movq %P[thread_info](%%rsi),%%r8\n\t" \
LOCK_PREFIX "btr %[tif_fork],%P[ti_flags](%%r8)\n\t" \
"movq %%rax,%%rdi\n\t" \
@@ -106,7 +106,7 @@ do { \
[ti_flags] "i" (offsetof(struct thread_info, flags)), \
[tif_fork] "i" (TIF_FORK), \
[thread_info] "i" (offsetof(struct task_struct, stack)), \
- [pda_pcurrent] "i" (offsetof(struct x8664_pda, pcurrent)) \
+ [current_task] "m" (per_cpu_var(current_task)) \
: "memory", "cc" __EXTRA_CLOBBER)
#endif
diff --git a/arch/x86/include/asm/thread_info.h b/arch/x86/include/asm/thread_info.h
index efdf938..f384889 100644
--- a/arch/x86/include/asm/thread_info.h
+++ b/arch/x86/include/asm/thread_info.h
@@ -196,25 +196,21 @@ static inline struct thread_info *current_thread_info(void)
#else /* X86_32 */
-#include <asm/pda.h>
+#include <asm/percpu.h>
+#define KERNEL_STACK_OFFSET (5*8)
/*
* macros/functions for gaining access to the thread information structure
* preempt_count needs to be 1 initially, until the scheduler is functional.
*/
#ifndef __ASSEMBLY__
-static inline struct thread_info *current_thread_info(void)
-{
- struct thread_info *ti;
- ti = (void *)(read_pda(kernelstack) + PDA_STACKOFFSET - THREAD_SIZE);
- return ti;
-}
+DECLARE_PER_CPU(unsigned long, kernel_stack);
-/* do not use in interrupt context */
-static inline struct thread_info *stack_thread_info(void)
+static inline struct thread_info *current_thread_info(void)
{
struct thread_info *ti;
- asm("andq %%rsp,%0; " : "=r" (ti) : "0" (~(THREAD_SIZE - 1)));
+ ti = (void *)(percpu_read(kernel_stack) +
+ KERNEL_STACK_OFFSET - THREAD_SIZE);
return ti;
}
@@ -222,8 +218,8 @@ static inline struct thread_info *stack_thread_info(void)
/* how to get the thread information struct from ASM */
#define GET_THREAD_INFO(reg) \
- movq %gs:pda_kernelstack,reg ; \
- subq $(THREAD_SIZE-PDA_STACKOFFSET),reg
+ movq PER_CPU_VAR(kernel_stack),reg ; \
+ subq $(THREAD_SIZE-KERNEL_STACK_OFFSET),reg
#endif
diff --git a/arch/x86/include/asm/tlbflush.h b/arch/x86/include/asm/tlbflush.h
index 0e7bbb5..d3539f9 100644
--- a/arch/x86/include/asm/tlbflush.h
+++ b/arch/x86/include/asm/tlbflush.h
@@ -113,7 +113,7 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
__flush_tlb();
}
-static inline void native_flush_tlb_others(const cpumask_t *cpumask,
+static inline void native_flush_tlb_others(const struct cpumask *cpumask,
struct mm_struct *mm,
unsigned long va)
{
@@ -142,31 +142,28 @@ static inline void flush_tlb_range(struct vm_area_struct *vma,
flush_tlb_mm(vma->vm_mm);
}
-void native_flush_tlb_others(const cpumask_t *cpumask, struct mm_struct *mm,
- unsigned long va);
+void native_flush_tlb_others(const struct cpumask *cpumask,
+ struct mm_struct *mm, unsigned long va);
#define TLBSTATE_OK 1
#define TLBSTATE_LAZY 2
-#ifdef CONFIG_X86_32
struct tlb_state {
struct mm_struct *active_mm;
int state;
- char __cacheline_padding[L1_CACHE_BYTES-8];
};
DECLARE_PER_CPU(struct tlb_state, cpu_tlbstate);
-void reset_lazy_tlbstate(void);
-#else
static inline void reset_lazy_tlbstate(void)
{
+ percpu_write(cpu_tlbstate.state, 0);
+ percpu_write(cpu_tlbstate.active_mm, &init_mm);
}
-#endif
#endif /* SMP */
#ifndef CONFIG_PARAVIRT
-#define flush_tlb_others(mask, mm, va) native_flush_tlb_others(&mask, mm, va)
+#define flush_tlb_others(mask, mm, va) native_flush_tlb_others(mask, mm, va)
#endif
static inline void flush_tlb_kernel_range(unsigned long start,
@@ -175,4 +172,6 @@ static inline void flush_tlb_kernel_range(unsigned long start,
flush_tlb_all();
}
+extern void zap_low_mappings(void);
+
#endif /* _ASM_X86_TLBFLUSH_H */
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h
index 4e2f2e0..ffea1fe 100644
--- a/arch/x86/include/asm/topology.h
+++ b/arch/x86/include/asm/topology.h
@@ -83,7 +83,8 @@ extern cpumask_t *node_to_cpumask_map;
DECLARE_EARLY_PER_CPU(int, x86_cpu_to_node_map);
/* Returns the number of the current Node. */
-#define numa_node_id() read_pda(nodenumber)
+DECLARE_PER_CPU(int, node_number);
+#define numa_node_id() percpu_read(node_number)
#ifdef CONFIG_DEBUG_PER_CPU_MAPS
extern int cpu_to_node(int cpu);
@@ -102,10 +103,7 @@ static inline int cpu_to_node(int cpu)
/* Same function but used if called before per_cpu areas are setup */
static inline int early_cpu_to_node(int cpu)
{
- if (early_per_cpu_ptr(x86_cpu_to_node_map))
- return early_per_cpu_ptr(x86_cpu_to_node_map)[cpu];
-
- return per_cpu(x86_cpu_to_node_map, cpu);
+ return early_per_cpu(x86_cpu_to_node_map, cpu);
}
/* Returns a pointer to the cpumask of CPUs on Node 'node'. */
diff --git a/arch/x86/include/asm/trampoline.h b/arch/x86/include/asm/trampoline.h
index 780ba0a..90f06c2 100644
--- a/arch/x86/include/asm/trampoline.h
+++ b/arch/x86/include/asm/trampoline.h
@@ -13,6 +13,7 @@ extern unsigned char *trampoline_base;
extern unsigned long init_rsp;
extern unsigned long initial_code;
+extern unsigned long initial_gs;
#define TRAMPOLINE_SIZE roundup(trampoline_end - trampoline_data, PAGE_SIZE)
#define TRAMPOLINE_BASE 0x6000
diff --git a/arch/x86/include/asm/uv/uv_bau.h b/arch/x86/include/asm/uv/uv_bau.h
index 50423c7..74e6393 100644
--- a/arch/x86/include/asm/uv/uv_bau.h
+++ b/arch/x86/include/asm/uv/uv_bau.h
@@ -325,7 +325,8 @@ static inline void bau_cpubits_clear(struct bau_local_cpumask *dstp, int nbits)
#define cpubit_isset(cpu, bau_local_cpumask) \
test_bit((cpu), (bau_local_cpumask).bits)
-extern int uv_flush_tlb_others(cpumask_t *, struct mm_struct *, unsigned long);
+extern int uv_flush_tlb_others(struct cpumask *,
+ struct mm_struct *, unsigned long);
extern void uv_bau_message_intr1(void);
extern void uv_bau_timeout_intr1(void);
diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c
index d37593c..4cb5964 100644
--- a/arch/x86/kernel/acpi/boot.c
+++ b/arch/x86/kernel/acpi/boot.c
@@ -912,8 +912,8 @@ static u8 __init uniq_ioapic_id(u8 id)
DECLARE_BITMAP(used, 256);
bitmap_zero(used, 256);
for (i = 0; i < nr_ioapics; i++) {
- struct mp_config_ioapic *ia = &mp_ioapics[i];
- __set_bit(ia->mp_apicid, used);
+ struct mpc_ioapic *ia = &mp_ioapics[i];
+ __set_bit(ia->apicid, used);
}
if (!test_bit(id, used))
return id;
@@ -945,47 +945,47 @@ void __init mp_register_ioapic(int id, u32 address, u32 gsi_base)
idx = nr_ioapics;
- mp_ioapics[idx].mp_type = MP_IOAPIC;
- mp_ioapics[idx].mp_flags = MPC_APIC_USABLE;
- mp_ioapics[idx].mp_apicaddr = address;
+ mp_ioapics[idx].type = MP_IOAPIC;
+ mp_ioapics[idx].flags = MPC_APIC_USABLE;
+ mp_ioapics[idx].apicaddr = address;
set_fixmap_nocache(FIX_IO_APIC_BASE_0 + idx, address);
- mp_ioapics[idx].mp_apicid = uniq_ioapic_id(id);
+ mp_ioapics[idx].apicid = uniq_ioapic_id(id);
#ifdef CONFIG_X86_32
- mp_ioapics[idx].mp_apicver = io_apic_get_version(idx);
+ mp_ioapics[idx].apicver = io_apic_get_version(idx);
#else
- mp_ioapics[idx].mp_apicver = 0;
+ mp_ioapics[idx].apicver = 0;
#endif
/*
* Build basic GSI lookup table to facilitate gsi->io_apic lookups
* and to prevent reprogramming of IOAPIC pins (PCI GSIs).
*/
- mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].mp_apicid;
+ mp_ioapic_routing[idx].apic_id = mp_ioapics[idx].apicid;
mp_ioapic_routing[idx].gsi_base = gsi_base;
mp_ioapic_routing[idx].gsi_end = gsi_base +
io_apic_get_redir_entries(idx);
- printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%lx, "
- "GSI %d-%d\n", idx, mp_ioapics[idx].mp_apicid,
- mp_ioapics[idx].mp_apicver, mp_ioapics[idx].mp_apicaddr,
+ printk(KERN_INFO "IOAPIC[%d]: apic_id %d, version %d, address 0x%x, "
+ "GSI %d-%d\n", idx, mp_ioapics[idx].apicid,
+ mp_ioapics[idx].apicver, mp_ioapics[idx].apicaddr,
mp_ioapic_routing[idx].gsi_base, mp_ioapic_routing[idx].gsi_end);
nr_ioapics++;
}
-static void assign_to_mp_irq(struct mp_config_intsrc *m,
- struct mp_config_intsrc *mp_irq)
+static void assign_to_mp_irq(struct mpc_intsrc *m,
+ struct mpc_intsrc *mp_irq)
{
- memcpy(mp_irq, m, sizeof(struct mp_config_intsrc));
+ memcpy(mp_irq, m, sizeof(struct mpc_intsrc));
}
-static int mp_irq_cmp(struct mp_config_intsrc *mp_irq,
- struct mp_config_intsrc *m)
+static int mp_irq_cmp(struct mpc_intsrc *mp_irq,
+ struct mpc_intsrc *m)
{
- return memcmp(mp_irq, m, sizeof(struct mp_config_intsrc));
+ return memcmp(mp_irq, m, sizeof(struct mpc_intsrc));
}
-static void save_mp_irq(struct mp_config_intsrc *m)
+static void save_mp_irq(struct mpc_intsrc *m)
{
int i;
@@ -1003,7 +1003,7 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
{
int ioapic;
int pin;
- struct mp_config_intsrc mp_irq;
+ struct mpc_intsrc mp_irq;
/*
* Convert 'gsi' to 'ioapic.pin'.
@@ -1021,13 +1021,13 @@ void __init mp_override_legacy_irq(u8 bus_irq, u8 polarity, u8 trigger, u32 gsi)
if ((bus_irq == 0) && (trigger == 3))
trigger = 1;
- mp_irq.mp_type = MP_INTSRC;
- mp_irq.mp_irqtype = mp_INT;
- mp_irq.mp_irqflag = (trigger << 2) | polarity;
- mp_irq.mp_srcbus = MP_ISA_BUS;
- mp_irq.mp_srcbusirq = bus_irq; /* IRQ */
- mp_irq.mp_dstapic = mp_ioapics[ioapic].mp_apicid; /* APIC ID */
- mp_irq.mp_dstirq = pin; /* INTIN# */
+ mp_irq.type = MP_INTSRC;
+ mp_irq.irqtype = mp_INT;
+ mp_irq.irqflag = (trigger << 2) | polarity;
+ mp_irq.srcbus = MP_ISA_BUS;
+ mp_irq.srcbusirq = bus_irq; /* IRQ */
+ mp_irq.dstapic = mp_ioapics[ioapic].apicid; /* APIC ID */
+ mp_irq.dstirq = pin; /* INTIN# */
save_mp_irq(&mp_irq);
}
@@ -1037,7 +1037,7 @@ void __init mp_config_acpi_legacy_irqs(void)
int i;
int ioapic;
unsigned int dstapic;
- struct mp_config_intsrc mp_irq;
+ struct mpc_intsrc mp_irq;
#if defined (CONFIG_MCA) || defined (CONFIG_EISA)
/*
@@ -1062,7 +1062,7 @@ void __init mp_config_acpi_legacy_irqs(void)
ioapic = mp_find_ioapic(0);
if (ioapic < 0)
return;
- dstapic = mp_ioapics[ioapic].mp_apicid;
+ dstapic = mp_ioapics[ioapic].apicid;
/*
* Use the default configuration for the IRQs 0-15. Unless
@@ -1072,16 +1072,14 @@ void __init mp_config_acpi_legacy_irqs(void)
int idx;
for (idx = 0; idx < mp_irq_entries; idx++) {
- struct mp_config_intsrc *irq = mp_irqs + idx;
+ struct mpc_intsrc *irq = mp_irqs + idx;
/* Do we already have a mapping for this ISA IRQ? */
- if (irq->mp_srcbus == MP_ISA_BUS
- && irq->mp_srcbusirq == i)
+ if (irq->srcbus == MP_ISA_BUS && irq->srcbusirq == i)
break;
/* Do we already have a mapping for this IOAPIC pin */
- if (irq->mp_dstapic == dstapic &&
- irq->mp_dstirq == i)
+ if (irq->dstapic == dstapic && irq->dstirq == i)
break;
}
@@ -1090,13 +1088,13 @@ void __init mp_config_acpi_legacy_irqs(void)
continue; /* IRQ already used */
}
- mp_irq.mp_type = MP_INTSRC;
- mp_irq.mp_irqflag = 0; /* Conforming */
- mp_irq.mp_srcbus = MP_ISA_BUS;
- mp_irq.mp_dstapic = dstapic;
- mp_irq.mp_irqtype = mp_INT;
- mp_irq.mp_srcbusirq = i; /* Identity mapped */
- mp_irq.mp_dstirq = i;
+ mp_irq.type = MP_INTSRC;
+ mp_irq.irqflag = 0; /* Conforming */
+ mp_irq.srcbus = MP_ISA_BUS;
+ mp_irq.dstapic = dstapic;
+ mp_irq.irqtype = mp_INT;
+ mp_irq.srcbusirq = i; /* Identity mapped */
+ mp_irq.dstirq = i;
save_mp_irq(&mp_irq);
}
@@ -1207,22 +1205,22 @@ int mp_config_acpi_gsi(unsigned char number, unsigned int devfn, u8 pin,
u32 gsi, int triggering, int polarity)
{
#ifdef CONFIG_X86_MPPARSE
- struct mp_config_intsrc mp_irq;
+ struct mpc_intsrc mp_irq;
int ioapic;
if (!acpi_ioapic)
return 0;
/* print the entry should happen on mptable identically */
- mp_irq.mp_type = MP_INTSRC;
- mp_irq.mp_irqtype = mp_INT;
- mp_irq.mp_irqflag = (triggering == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) |
+ mp_irq.type = MP_INTSRC;
+ mp_irq.irqtype = mp_INT;
+ mp_irq.irqflag = (triggering == ACPI_EDGE_SENSITIVE ? 4 : 0x0c) |
(polarity == ACPI_ACTIVE_HIGH ? 1 : 3);
- mp_irq.mp_srcbus = number;
- mp_irq.mp_srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3);
+ mp_irq.srcbus = number;
+ mp_irq.srcbusirq = (((devfn >> 3) & 0x1f) << 2) | ((pin - 1) & 3);
ioapic = mp_find_ioapic(gsi);
- mp_irq.mp_dstapic = mp_ioapic_routing[ioapic].apic_id;
- mp_irq.mp_dstirq = gsi - mp_ioapic_routing[ioapic].gsi_base;
+ mp_irq.dstapic = mp_ioapic_routing[ioapic].apic_id;
+ mp_irq.dstirq = gsi - mp_ioapic_routing[ioapic].gsi_base;
save_mp_irq(&mp_irq);
#endif
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c
index 707c1f6..4abff45 100644
--- a/arch/x86/kernel/acpi/sleep.c
+++ b/arch/x86/kernel/acpi/sleep.c
@@ -101,6 +101,7 @@ int acpi_save_state_mem(void)
stack_start.sp = temp_stack + sizeof(temp_stack);
early_gdt_descr.address =
(unsigned long)get_cpu_gdt_table(smp_processor_id());
+ initial_gs = per_cpu_offset(smp_processor_id());
#endif
initial_code = (unsigned long)wakeup_long64;
saved_magic = 0x123456789abcdef0;
diff --git a/arch/x86/kernel/apic.c b/arch/x86/kernel/apic.c
index d2d17b8..e9af14f 100644
--- a/arch/x86/kernel/apic.c
+++ b/arch/x86/kernel/apic.c
@@ -48,6 +48,7 @@
#include <asm/proto.h>
#include <asm/apic.h>
#include <asm/i8259.h>
+#include <asm/smp.h>
#include <mach_apic.h>
#include <mach_apicdef.h>
@@ -895,6 +896,10 @@ void disable_local_APIC(void)
{
unsigned int value;
+ /* APIC hasn't been mapped yet */
+ if (!apic_phys)
+ return;
+
clear_local_APIC();
/*
@@ -1126,6 +1131,11 @@ void __cpuinit setup_local_APIC(void)
unsigned int value;
int i, j;
+ if (disable_apic) {
+ disable_ioapic_setup();
+ return;
+ }
+
#ifdef CONFIG_X86_32
/* Pound the ESR really hard over the head with a big hammer - mbligh */
if (lapic_is_integrated() && esr_disable) {
@@ -1567,11 +1577,11 @@ int apic_version[MAX_APICS];
int __init APIC_init_uniprocessor(void)
{
-#ifdef CONFIG_X86_64
if (disable_apic) {
pr_info("Apic disabled\n");
return -1;
}
+#ifdef CONFIG_X86_64
if (!cpu_has_apic) {
disable_apic = 1;
pr_info("Apic disabled by BIOS\n");
@@ -1869,17 +1879,8 @@ void __cpuinit generic_processor_info(int apicid, int version)
#endif
#if defined(CONFIG_X86_SMP) || defined(CONFIG_X86_64)
- /* are we being called early in kernel startup? */
- if (early_per_cpu_ptr(x86_cpu_to_apicid)) {
- u16 *cpu_to_apicid = early_per_cpu_ptr(x86_cpu_to_apicid);
- u16 *bios_cpu_apicid = early_per_cpu_ptr(x86_bios_cpu_apicid);
-
- cpu_to_apicid[cpu] = apicid;
- bios_cpu_apicid[cpu] = apicid;
- } else {
- per_cpu(x86_cpu_to_apicid, cpu) = apicid;
- per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
- }
+ early_per_cpu(x86_cpu_to_apicid, cpu) = apicid;
+ early_per_cpu(x86_bios_cpu_apicid, cpu) = apicid;
#endif
set_cpu_possible(cpu, true);
diff --git a/arch/x86/kernel/asm-offsets_64.c b/arch/x86/kernel/asm-offsets_64.c
index 1d41d3f..64c834a 100644
--- a/arch/x86/kernel/asm-offsets_64.c
+++ b/arch/x86/kernel/asm-offsets_64.c
@@ -49,13 +49,7 @@ int main(void)
BLANK();
#undef ENTRY
#define ENTRY(entry) DEFINE(pda_ ## entry, offsetof(struct x8664_pda, entry))
- ENTRY(kernelstack);
- ENTRY(oldrsp);
- ENTRY(pcurrent);
- ENTRY(irqcount);
- ENTRY(cpunumber);
- ENTRY(irqstackptr);
- ENTRY(data_offset);
+ DEFINE(pda_size, sizeof(struct x8664_pda));
BLANK();
#undef ENTRY
#ifdef CONFIG_PARAVIRT
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index 667e5d5..95eb30e 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -22,6 +22,8 @@
#include <asm/asm.h>
#include <asm/numa.h>
#include <asm/smp.h>
+#include <asm/cpu.h>
+#include <asm/cpumask.h>
#ifdef CONFIG_X86_LOCAL_APIC
#include <asm/mpspec.h>
#include <asm/apic.h>
@@ -879,54 +881,34 @@ static __init int setup_disablecpuid(char *arg)
__setup("clearcpuid=", setup_disablecpuid);
#ifdef CONFIG_X86_64
-struct x8664_pda **_cpu_pda __read_mostly;
-EXPORT_SYMBOL(_cpu_pda);
-
struct desc_ptr idt_descr = { 256 * 16 - 1, (unsigned long) idt_table };
-static char boot_cpu_stack[IRQSTACKSIZE] __page_aligned_bss;
+DEFINE_PER_CPU_PAGE_ALIGNED(char[IRQ_STACK_SIZE], irq_stack);
+#ifdef CONFIG_SMP
+DEFINE_PER_CPU(char *, irq_stack_ptr); /* will be set during per cpu init */
+#else
+DEFINE_PER_CPU(char *, irq_stack_ptr) =
+ per_cpu_var(irq_stack) + IRQ_STACK_SIZE - 64;
+#endif
+
+DEFINE_PER_CPU(unsigned long, kernel_stack) =
+ (unsigned long)&init_thread_union - KERNEL_STACK_OFFSET + THREAD_SIZE;
+EXPORT_PER_CPU_SYMBOL(kernel_stack);
+
+DEFINE_PER_CPU(unsigned int, irq_count) = -1;
void __cpuinit pda_init(int cpu)
{
- struct x8664_pda *pda = cpu_pda(cpu);
-
/* Setup up data that may be needed in __get_free_pages early */
loadsegment(fs, 0);
loadsegment(gs, 0);
- /* Memory clobbers used to order PDA accessed */
- mb();
- wrmsrl(MSR_GS_BASE, pda);
- mb();
-
- pda->cpunumber = cpu;
- pda->irqcount = -1;
- pda->kernelstack = (unsigned long)stack_thread_info() -
- PDA_STACKOFFSET + THREAD_SIZE;
- pda->active_mm = &init_mm;
- pda->mmu_state = 0;
-
- if (cpu == 0) {
- /* others are initialized in smpboot.c */
- pda->pcurrent = &init_task;
- pda->irqstackptr = boot_cpu_stack;
- pda->irqstackptr += IRQSTACKSIZE - 64;
- } else {
- if (!pda->irqstackptr) {
- pda->irqstackptr = (char *)
- __get_free_pages(GFP_ATOMIC, IRQSTACK_ORDER);
- if (!pda->irqstackptr)
- panic("cannot allocate irqstack for cpu %d",
- cpu);
- pda->irqstackptr += IRQSTACKSIZE - 64;
- }
- if (pda->nodenumber == 0 && cpu_to_node(cpu) != NUMA_NO_NODE)
- pda->nodenumber = cpu_to_node(cpu);
- }
+ load_pda_offset(cpu);
}
-static char boot_exception_stacks[(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ +
- DEBUG_STKSZ] __page_aligned_bss;
+static DEFINE_PER_CPU_PAGE_ALIGNED(char, exception_stacks
+ [(N_EXCEPTION_STACKS - 1) * EXCEPTION_STKSZ + DEBUG_STKSZ])
+ __aligned(PAGE_SIZE);
extern asmlinkage void ignore_sysret(void);
@@ -984,15 +966,18 @@ void __cpuinit cpu_init(void)
struct tss_struct *t = &per_cpu(init_tss, cpu);
struct orig_ist *orig_ist = &per_cpu(orig_ist, cpu);
unsigned long v;
- char *estacks = NULL;
struct task_struct *me;
int i;
/* CPU 0 is initialised in head64.c */
if (cpu != 0)
pda_init(cpu);
- else
- estacks = boot_exception_stacks;
+
+#ifdef CONFIG_NUMA
+ if (cpu != 0 && percpu_read(node_number) == 0 &&
+ cpu_to_node(cpu) != NUMA_NO_NODE)
+ percpu_write(node_number, cpu_to_node(cpu));
+#endif
me = current;
@@ -1026,18 +1011,13 @@ void __cpuinit cpu_init(void)
* set up and load the per-CPU TSS
*/
if (!orig_ist->ist[0]) {
- static const unsigned int order[N_EXCEPTION_STACKS] = {
- [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STACK_ORDER,
- [DEBUG_STACK - 1] = DEBUG_STACK_ORDER
+ static const unsigned int sizes[N_EXCEPTION_STACKS] = {
+ [0 ... N_EXCEPTION_STACKS - 1] = EXCEPTION_STKSZ,
+ [DEBUG_STACK - 1] = DEBUG_STKSZ
};
+ char *estacks = per_cpu(exception_stacks, cpu);
for (v = 0; v < N_EXCEPTION_STACKS; v++) {
- if (cpu) {
- estacks = (char *)__get_free_pages(GFP_ATOMIC, order[v]);
- if (!estacks)
- panic("Cannot allocate exception "
- "stack %ld %d\n", v, cpu);
- }
- estacks += PAGE_SIZE << order[v];
+ estacks += sizes[v];
orig_ist->ist[v] = t->x86_tss.ist[v] =
(unsigned long)estacks;
}
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index 06fcd8f..8f3c95c 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -150,9 +150,8 @@ struct drv_cmd {
u32 val;
};
-static long do_drv_read(void *_cmd)
+static void do_drv_read(struct drv_cmd *cmd)
{
- struct drv_cmd *cmd = _cmd;
u32 h;
switch (cmd->type) {
@@ -167,12 +166,10 @@ static long do_drv_read(void *_cmd)
default:
break;
}
- return 0;
}
-static long do_drv_write(void *_cmd)
+static void do_drv_write(struct drv_cmd *cmd)
{
- struct drv_cmd *cmd = _cmd;
u32 lo, hi;
switch (cmd->type) {
@@ -189,23 +186,30 @@ static long do_drv_write(void *_cmd)
default:
break;
}
- return 0;
}
static void drv_read(struct drv_cmd *cmd)
{
+ cpumask_t saved_mask = current->cpus_allowed;
cmd->val = 0;
- work_on_cpu(cpumask_any(cmd->mask), do_drv_read, cmd);
+ set_cpus_allowed_ptr(current, cmd->mask);
+ do_drv_read(cmd);
+ set_cpus_allowed_ptr(current, &saved_mask);
}
static void drv_write(struct drv_cmd *cmd)
{
+ cpumask_t saved_mask = current->cpus_allowed;
unsigned int i;
for_each_cpu(i, cmd->mask) {
- work_on_cpu(i, do_drv_write, cmd);
+ set_cpus_allowed_ptr(current, cpumask_of(i));
+ do_drv_write(cmd);
}
+
+ set_cpus_allowed_ptr(current, &saved_mask);
+ return;
}
static u32 get_cur_val(const struct cpumask *mask)
@@ -231,15 +235,8 @@ static u32 get_cur_val(const struct cpumask *mask)
return 0;
}
- if (unlikely(!alloc_cpumask_var(&cmd.mask, GFP_KERNEL)))
- return 0;
-
- cpumask_copy(cmd.mask, mask);
-
drv_read(&cmd);
- free_cpumask_var(cmd.mask);
-
dprintk("get_cur_val = %u\n", cmd.val);
return cmd.val;
diff --git a/arch/x86/kernel/cpu/intel_cacheinfo.c b/arch/x86/kernel/cpu/intel_cacheinfo.c
index 48533d7..58527a9 100644
--- a/arch/x86/kernel/cpu/intel_cacheinfo.c
+++ b/arch/x86/kernel/cpu/intel_cacheinfo.c
@@ -132,7 +132,16 @@ struct _cpuid4_info {
union _cpuid4_leaf_ecx ecx;
unsigned long size;
unsigned long can_disable;
- cpumask_t shared_cpu_map; /* future?: only cpus/node is needed */
+ DECLARE_BITMAP(shared_cpu_map, NR_CPUS);
+};
+
+/* subset of above _cpuid4_info w/o shared_cpu_map */
+struct _cpuid4_info_regs {
+ union _cpuid4_leaf_eax eax;
+ union _cpuid4_leaf_ebx ebx;
+ union _cpuid4_leaf_ecx ecx;
+ unsigned long size;
+ unsigned long can_disable;
};
#ifdef CONFIG_PCI
@@ -263,7 +272,7 @@ amd_cpuid4(int leaf, union _cpuid4_leaf_eax *eax,
}
static void __cpuinit
-amd_check_l3_disable(int index, struct _cpuid4_info *this_leaf)
+amd_check_l3_disable(int index, struct _cpuid4_info_regs *this_leaf)
{
if (index < 3)
return;
@@ -271,7 +280,8 @@ amd_check_l3_disable(int index, struct _cpuid4_info *this_leaf)
}
static int
-__cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
+__cpuinit cpuid4_cache_lookup_regs(int index,
+ struct _cpuid4_info_regs *this_leaf)
{
union _cpuid4_leaf_eax eax;
union _cpuid4_leaf_ebx ebx;
@@ -299,6 +309,15 @@ __cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
return 0;
}
+static int
+__cpuinit cpuid4_cache_lookup(int index, struct _cpuid4_info *this_leaf)
+{
+ struct _cpuid4_info_regs *leaf_regs =
+ (struct _cpuid4_info_regs *)this_leaf;
+
+ return cpuid4_cache_lookup_regs(index, leaf_regs);
+}
+
static int __cpuinit find_num_cache_leaves(void)
{
unsigned int eax, ebx, ecx, edx;
@@ -338,11 +357,10 @@ unsigned int __cpuinit init_intel_cacheinfo(struct cpuinfo_x86 *c)
* parameters cpuid leaf to find the cache details
*/
for (i = 0; i < num_cache_leaves; i++) {
- struct _cpuid4_info this_leaf;
-
+ struct _cpuid4_info_regs this_leaf;
int retval;
- retval = cpuid4_cache_lookup(i, &this_leaf);
+ retval = cpuid4_cache_lookup_regs(i, &this_leaf);
if (retval >= 0) {
switch(this_leaf.eax.split.level) {
case 1:
@@ -491,17 +509,20 @@ static void __cpuinit cache_shared_cpu_map_setup(unsigned int cpu, int index)
num_threads_sharing = 1 + this_leaf->eax.split.num_threads_sharing;
if (num_threads_sharing == 1)
- cpu_set(cpu, this_leaf->shared_cpu_map);
+ cpumask_set_cpu(cpu, to_cpumask(this_leaf->shared_cpu_map));
else {
index_msb = get_count_order(num_threads_sharing);
for_each_online_cpu(i) {
if (cpu_data(i).apicid >> index_msb ==
c->apicid >> index_msb) {
- cpu_set(i, this_leaf->shared_cpu_map);
+ cpumask_set_cpu(i,
+ to_cpumask(this_leaf->shared_cpu_map));
if (i != cpu && per_cpu(cpuid4_info, i)) {
- sibling_leaf = CPUID4_INFO_IDX(i, index);
- cpu_set(cpu, sibling_leaf->shared_cpu_map);
+ sibling_leaf =
+ CPUID4_INFO_IDX(i, index);
+ cpumask_set_cpu(cpu, to_cpumask(
+ sibling_leaf->shared_cpu_map));
}
}
}
@@ -513,9 +534,10 @@ static void __cpuinit cache_remove_shared_cpu_map(unsigned int cpu, int index)
int sibling;
this_leaf = CPUID4_INFO_IDX(cpu, index);
- for_each_cpu_mask_nr(sibling, this_leaf->shared_cpu_map) {
+ for_each_cpu(sibling, to_cpumask(this_leaf->shared_cpu_map)) {
sibling_leaf = CPUID4_INFO_IDX(sibling, index);
- cpu_clear(cpu, sibling_leaf->shared_cpu_map);
+ cpumask_clear_cpu(cpu,
+ to_cpumask(sibling_leaf->shared_cpu_map));
}
}
#else
@@ -620,8 +642,9 @@ static ssize_t show_shared_cpu_map_func(struct _cpuid4_info *this_leaf,
int n = 0;
if (len > 1) {
- cpumask_t *mask = &this_leaf->shared_cpu_map;
+ const struct cpumask *mask;
+ mask = to_cpumask(this_leaf->shared_cpu_map);
n = type?
cpulist_scnprintf(buf, len-2, mask) :
cpumask_scnprintf(buf, len-2, mask);
@@ -684,7 +707,8 @@ static struct pci_dev *get_k8_northbridge(int node)
static ssize_t show_cache_disable(struct _cpuid4_info *this_leaf, char *buf)
{
- int node = cpu_to_node(first_cpu(this_leaf->shared_cpu_map));
+ const struct cpumask *mask = to_cpumask(this_leaf->shared_cpu_map);
+ int node = cpu_to_node(cpumask_first(mask));
struct pci_dev *dev = NULL;
ssize_t ret = 0;
int i;
@@ -718,7 +742,8 @@ static ssize_t
store_cache_disable(struct _cpuid4_info *this_leaf, const char *buf,
size_t count)
{
- int node = cpu_to_node(first_cpu(this_leaf->shared_cpu_map));
+ const struct cpumask *mask = to_cpumask(this_leaf->shared_cpu_map);
+ int node = cpu_to_node(cpumask_first(mask));
struct pci_dev *dev = NULL;
unsigned int ret, index, val;
@@ -863,7 +888,7 @@ err_out:
return -ENOMEM;
}
-static cpumask_t cache_dev_map = CPU_MASK_NONE;
+static DECLARE_BITMAP(cache_dev_map, NR_CPUS);
/* Add/Remove cache interface for CPU device */
static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
@@ -903,7 +928,7 @@ static int __cpuinit cache_add_dev(struct sys_device * sys_dev)
}
kobject_uevent(&(this_object->kobj), KOBJ_ADD);
}
- cpu_set(cpu, cache_dev_map);
+ cpumask_set_cpu(cpu, to_cpumask(cache_dev_map));
kobject_uevent(per_cpu(cache_kobject, cpu), KOBJ_ADD);
return 0;
@@ -916,9 +941,9 @@ static void __cpuinit cache_remove_dev(struct sys_device * sys_dev)
if (per_cpu(cpuid4_info, cpu) == NULL)
return;
- if (!cpu_isset(cpu, cache_dev_map))
+ if (!cpumask_test_cpu(cpu, to_cpumask(cache_dev_map)))
return;
- cpu_clear(cpu, cache_dev_map);
+ cpumask_clear_cpu(cpu, to_cpumask(cache_dev_map));
for (i = 0; i < num_cache_leaves; i++)
kobject_put(&(INDEX_KOBJECT_PTR(cpu,i)->kobj));
diff --git a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
index 8ae8c4f..4772e91 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_amd_64.c
@@ -67,7 +67,7 @@ static struct threshold_block threshold_defaults = {
struct threshold_bank {
struct kobject *kobj;
struct threshold_block *blocks;
- cpumask_t cpus;
+ cpumask_var_t cpus;
};
static DEFINE_PER_CPU(struct threshold_bank *, threshold_banks[NR_BANKS]);
@@ -481,7 +481,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
#ifdef CONFIG_SMP
if (cpu_data(cpu).cpu_core_id && shared_bank[bank]) { /* symlink */
- i = first_cpu(per_cpu(cpu_core_map, cpu));
+ i = cpumask_first(&per_cpu(cpu_core_map, cpu));
/* first core not up yet */
if (cpu_data(i).cpu_core_id)
@@ -501,7 +501,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
if (err)
goto out;
- b->cpus = per_cpu(cpu_core_map, cpu);
+ cpumask_copy(b->cpus, &per_cpu(cpu_core_map, cpu));
per_cpu(threshold_banks, cpu)[bank] = b;
goto out;
}
@@ -512,15 +512,20 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
err = -ENOMEM;
goto out;
}
+ if (!alloc_cpumask_var(&b->cpus, GFP_KERNEL)) {
+ kfree(b);
+ err = -ENOMEM;
+ goto out;
+ }
b->kobj = kobject_create_and_add(name, &per_cpu(device_mce, cpu).kobj);
if (!b->kobj)
goto out_free;
#ifndef CONFIG_SMP
- b->cpus = CPU_MASK_ALL;
+ cpumask_setall(b->cpus);
#else
- b->cpus = per_cpu(cpu_core_map, cpu);
+ cpumask_copy(b->cpus, &per_cpu(cpu_core_map, cpu));
#endif
per_cpu(threshold_banks, cpu)[bank] = b;
@@ -529,7 +534,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
if (err)
goto out_free;
- for_each_cpu_mask_nr(i, b->cpus) {
+ for_each_cpu(i, b->cpus) {
if (i == cpu)
continue;
@@ -545,6 +550,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
out_free:
per_cpu(threshold_banks, cpu)[bank] = NULL;
+ free_cpumask_var(b->cpus);
kfree(b);
out:
return err;
@@ -619,7 +625,7 @@ static void threshold_remove_bank(unsigned int cpu, int bank)
#endif
/* remove all sibling symlinks before unregistering */
- for_each_cpu_mask_nr(i, b->cpus) {
+ for_each_cpu(i, b->cpus) {
if (i == cpu)
continue;
@@ -632,6 +638,7 @@ static void threshold_remove_bank(unsigned int cpu, int bank)
free_out:
kobject_del(b->kobj);
kobject_put(b->kobj);
+ free_cpumask_var(b->cpus);
kfree(b);
per_cpu(threshold_banks, cpu)[bank] = NULL;
}
diff --git a/arch/x86/kernel/crash.c b/arch/x86/kernel/crash.c
index c689d19..11b93ca 100644
--- a/arch/x86/kernel/crash.c
+++ b/arch/x86/kernel/crash.c
@@ -24,7 +24,7 @@
#include <asm/apic.h>
#include <asm/hpet.h>
#include <linux/kdebug.h>
-#include <asm/smp.h>
+#include <asm/cpu.h>
#include <asm/reboot.h>
#include <asm/virtext.h>
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
index c302d07..d35db59 100644
--- a/arch/x86/kernel/dumpstack_64.c
+++ b/arch/x86/kernel/dumpstack_64.c
@@ -106,7 +106,8 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
const struct stacktrace_ops *ops, void *data)
{
const unsigned cpu = get_cpu();
- unsigned long *irqstack_end = (unsigned long *)cpu_pda(cpu)->irqstackptr;
+ unsigned long *irq_stack_end =
+ (unsigned long *)per_cpu(irq_stack_ptr, cpu);
unsigned used = 0;
struct thread_info *tinfo;
int graph = 0;
@@ -160,23 +161,23 @@ void dump_trace(struct task_struct *task, struct pt_regs *regs,
stack = (unsigned long *) estack_end[-2];
continue;
}
- if (irqstack_end) {
- unsigned long *irqstack;
- irqstack = irqstack_end -
- (IRQSTACKSIZE - 64) / sizeof(*irqstack);
+ if (irq_stack_end) {
+ unsigned long *irq_stack;
+ irq_stack = irq_stack_end -
+ (IRQ_STACK_SIZE - 64) / sizeof(*irq_stack);
- if (stack >= irqstack && stack < irqstack_end) {
+ if (stack >= irq_stack && stack < irq_stack_end) {
if (ops->stack(data, "IRQ") < 0)
break;
bp = print_context_stack(tinfo, stack, bp,
- ops, data, irqstack_end, &graph);
+ ops, data, irq_stack_end, &graph);
/*
* We link to the next stack (which would be
* the process stack normally) the last
* pointer (index -1 to end) in the IRQ stack:
*/
- stack = (unsigned long *) (irqstack_end[-1]);
- irqstack_end = NULL;
+ stack = (unsigned long *) (irq_stack_end[-1]);
+ irq_stack_end = NULL;
ops->stack(data, "EOI");
continue;
}
@@ -199,10 +200,10 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
unsigned long *stack;
int i;
const int cpu = smp_processor_id();
- unsigned long *irqstack_end =
- (unsigned long *) (cpu_pda(cpu)->irqstackptr);
- unsigned long *irqstack =
- (unsigned long *) (cpu_pda(cpu)->irqstackptr - IRQSTACKSIZE);
+ unsigned long *irq_stack_end =
+ (unsigned long *)(per_cpu(irq_stack_ptr, cpu));
+ unsigned long *irq_stack =
+ (unsigned long *)(per_cpu(irq_stack_ptr, cpu) - IRQ_STACK_SIZE);
/*
* debugging aid: "show_stack(NULL, NULL);" prints the
@@ -218,9 +219,9 @@ show_stack_log_lvl(struct task_struct *task, struct pt_regs *regs,
stack = sp;
for (i = 0; i < kstack_depth_to_print; i++) {
- if (stack >= irqstack && stack <= irqstack_end) {
- if (stack == irqstack_end) {
- stack = (unsigned long *) (irqstack_end[-1]);
+ if (stack >= irq_stack && stack <= irq_stack_end) {
+ if (stack == irq_stack_end) {
+ stack = (unsigned long *) (irq_stack_end[-1]);
printk(" <EOI> ");
}
} else {
@@ -241,7 +242,7 @@ void show_registers(struct pt_regs *regs)
int i;
unsigned long sp;
const int cpu = smp_processor_id();
- struct task_struct *cur = cpu_pda(cpu)->pcurrent;
+ struct task_struct *cur = current;
sp = regs->sp;
printk("CPU %d ", cpu);
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
index d6f0490..4646902 100644
--- a/arch/x86/kernel/entry_32.S
+++ b/arch/x86/kernel/entry_32.S
@@ -1203,7 +1203,6 @@ nmi_stack_correct:
pushl %eax
CFI_ADJUST_CFA_OFFSET 4
SAVE_ALL
- TRACE_IRQS_OFF
xorl %edx,%edx # zero error code
movl %esp,%eax # pt_regs pointer
call do_nmi
@@ -1244,7 +1243,6 @@ nmi_espfix_stack:
pushl %eax
CFI_ADJUST_CFA_OFFSET 4
SAVE_ALL
- TRACE_IRQS_OFF
FIXUP_ESPFIX_STACK # %eax == %esp
xorl %edx,%edx # zero error code
call do_nmi
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
index 1954a96..c092e7d 100644
--- a/arch/x86/kernel/entry_64.S
+++ b/arch/x86/kernel/entry_64.S
@@ -52,6 +52,7 @@
#include <asm/irqflags.h>
#include <asm/paravirt.h>
#include <asm/ftrace.h>
+#include <asm/percpu.h>
/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
#include <linux/elf-em.h>
@@ -209,7 +210,7 @@ ENTRY(native_usergs_sysret64)
/* %rsp:at FRAMEEND */
.macro FIXUP_TOP_OF_STACK tmp offset=0
- movq %gs:pda_oldrsp,\tmp
+ movq PER_CPU_VAR(old_rsp),\tmp
movq \tmp,RSP+\offset(%rsp)
movq $__USER_DS,SS+\offset(%rsp)
movq $__USER_CS,CS+\offset(%rsp)
@@ -220,7 +221,7 @@ ENTRY(native_usergs_sysret64)
.macro RESTORE_TOP_OF_STACK tmp offset=0
movq RSP+\offset(%rsp),\tmp
- movq \tmp,%gs:pda_oldrsp
+ movq \tmp,PER_CPU_VAR(old_rsp)
movq EFLAGS+\offset(%rsp),\tmp
movq \tmp,R11+\offset(%rsp)
.endm
@@ -336,15 +337,15 @@ ENTRY(save_args)
je 1f
SWAPGS
/*
- * irqcount is used to check if a CPU is already on an interrupt stack
+ * irq_count is used to check if a CPU is already on an interrupt stack
* or not. While this is essentially redundant with preempt_count it is
* a little cheaper to use a separate counter in the PDA (short of
* moving irq_enter into assembly, which would be too much work)
*/
-1: incl %gs:pda_irqcount
+1: incl PER_CPU_VAR(irq_count)
jne 2f
popq_cfi %rax /* move return address... */
- mov %gs:pda_irqstackptr,%rsp
+ mov PER_CPU_VAR(irq_stack_ptr),%rsp
EMPTY_FRAME 0
pushq_cfi %rax /* ... to the new stack */
/*
@@ -467,7 +468,7 @@ END(ret_from_fork)
ENTRY(system_call)
CFI_STARTPROC simple
CFI_SIGNAL_FRAME
- CFI_DEF_CFA rsp,PDA_STACKOFFSET
+ CFI_DEF_CFA rsp,KERNEL_STACK_OFFSET
CFI_REGISTER rip,rcx
/*CFI_REGISTER rflags,r11*/
SWAPGS_UNSAFE_STACK
@@ -478,8 +479,8 @@ ENTRY(system_call)
*/
ENTRY(system_call_after_swapgs)
- movq %rsp,%gs:pda_oldrsp
- movq %gs:pda_kernelstack,%rsp
+ movq %rsp,PER_CPU_VAR(old_rsp)
+ movq PER_CPU_VAR(kernel_stack),%rsp
/*
* No need to follow this irqs off/on section - it's straight
* and short:
@@ -522,7 +523,7 @@ sysret_check:
CFI_REGISTER rip,rcx
RESTORE_ARGS 0,-ARG_SKIP,1
/*CFI_REGISTER rflags,r11*/
- movq %gs:pda_oldrsp, %rsp
+ movq PER_CPU_VAR(old_rsp), %rsp
USERGS_SYSRET64
CFI_RESTORE_STATE
@@ -832,11 +833,11 @@ common_interrupt:
XCPT_FRAME
addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */
interrupt do_IRQ
- /* 0(%rsp): oldrsp-ARGOFFSET */
+ /* 0(%rsp): old_rsp-ARGOFFSET */
ret_from_intr:
DISABLE_INTERRUPTS(CLBR_NONE)
TRACE_IRQS_OFF
- decl %gs:pda_irqcount
+ decl PER_CPU_VAR(irq_count)
leaveq
CFI_DEF_CFA_REGISTER rsp
CFI_ADJUST_CFA_OFFSET -8
@@ -1077,10 +1078,10 @@ ENTRY(\sym)
TRACE_IRQS_OFF
movq %rsp,%rdi /* pt_regs pointer */
xorl %esi,%esi /* no error code */
- movq %gs:pda_data_offset, %rbp
- subq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
+ PER_CPU(init_tss, %rbp)
+ subq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
call \do_sym
- addq $EXCEPTION_STKSZ, per_cpu__init_tss + TSS_ist + (\ist - 1) * 8(%rbp)
+ addq $EXCEPTION_STKSZ, TSS_ist + (\ist - 1) * 8(%rbp)
jmp paranoid_exit /* %ebx: no swapgs flag */
CFI_ENDPROC
END(\sym)
@@ -1264,14 +1265,14 @@ ENTRY(call_softirq)
CFI_REL_OFFSET rbp,0
mov %rsp,%rbp
CFI_DEF_CFA_REGISTER rbp
- incl %gs:pda_irqcount
- cmove %gs:pda_irqstackptr,%rsp
+ incl PER_CPU_VAR(irq_count)
+ cmove PER_CPU_VAR(irq_stack_ptr),%rsp
push %rbp # backlink for old unwinder
call __do_softirq
leaveq
CFI_DEF_CFA_REGISTER rsp
CFI_ADJUST_CFA_OFFSET -8
- decl %gs:pda_irqcount
+ decl PER_CPU_VAR(irq_count)
ret
CFI_ENDPROC
END(call_softirq)
@@ -1301,15 +1302,15 @@ ENTRY(xen_do_hypervisor_callback) # do_hypervisor_callback(struct *pt_regs)
movq %rdi, %rsp # we don't return, adjust the stack frame
CFI_ENDPROC
DEFAULT_FRAME
-11: incl %gs:pda_irqcount
+11: incl PER_CPU_VAR(irq_count)
movq %rsp,%rbp
CFI_DEF_CFA_REGISTER rbp
- cmovzq %gs:pda_irqstackptr,%rsp
+ cmovzq PER_CPU_VAR(irq_stack_ptr),%rsp
pushq %rbp # backlink for old unwinder
call xen_evtchn_do_upcall
popq %rsp
CFI_DEF_CFA_REGISTER rsp
- decl %gs:pda_irqcount
+ decl PER_CPU_VAR(irq_count)
jmp error_exit
CFI_ENDPROC
END(do_hypervisor_callback)
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c
index b9a4d8c..af67d32 100644
--- a/arch/x86/kernel/head64.c
+++ b/arch/x86/kernel/head64.c
@@ -26,27 +26,6 @@
#include <asm/bios_ebda.h>
#include <asm/trampoline.h>
-/* boot cpu pda */
-static struct x8664_pda _boot_cpu_pda;
-
-#ifdef CONFIG_SMP
-/*
- * We install an empty cpu_pda pointer table to indicate to early users
- * (numa_set_node) that the cpu_pda pointer table for cpus other than
- * the boot cpu is not yet setup.
- */
-static struct x8664_pda *__cpu_pda[NR_CPUS] __initdata;
-#else
-static struct x8664_pda *__cpu_pda[NR_CPUS] __read_mostly;
-#endif
-
-void __init x86_64_init_pda(void)
-{
- _cpu_pda = __cpu_pda;
- cpu_pda(0) = &_boot_cpu_pda;
- pda_init(0);
-}
-
static void __init zap_identity_mappings(void)
{
pgd_t *pgd = pgd_offset_k(0UL);
@@ -112,7 +91,7 @@ void __init x86_64_start_kernel(char * real_mode_data)
if (console_loglevel == 10)
early_printk("Kernel alive\n");
- x86_64_init_pda();
+ pda_init(0);
x86_64_start_reservations(real_mode_data);
}
diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S
index 0e275d4..c8ace88 100644
--- a/arch/x86/kernel/head_64.S
+++ b/arch/x86/kernel/head_64.S
@@ -19,6 +19,7 @@
#include <asm/msr.h>
#include <asm/cache.h>
#include <asm/processor-flags.h>
+#include <asm/percpu.h>
#ifdef CONFIG_PARAVIRT
#include <asm/asm-offsets.h>
@@ -204,6 +205,23 @@ ENTRY(secondary_startup_64)
pushq $0
popfq
+#ifdef CONFIG_SMP
+ /*
+ * early_gdt_base should point to the gdt_page in static percpu init
+ * data area. Computing this requires two symbols - __per_cpu_load
+ * and per_cpu__gdt_page. As linker can't do no such relocation, do
+ * it by hand. As early_gdt_descr is manipulated by C code for
+ * secondary CPUs, this should be done only once for the boot CPU
+ * when early_gdt_descr_base contains zero.
+ */
+ movq early_gdt_descr_base(%rip), %rax
+ testq %rax, %rax
+ jnz 1f
+ movq $__per_cpu_load, %rax
+ addq $per_cpu__gdt_page, %rax
+ movq %rax, early_gdt_descr_base(%rip)
+1:
+#endif
/*
* We must switch to a new descriptor in kernel space for the GDT
* because soon the kernel won't have access anymore to the userspace
@@ -226,12 +244,18 @@ ENTRY(secondary_startup_64)
movl %eax,%fs
movl %eax,%gs
- /*
- * Setup up a dummy PDA. this is just for some early bootup code
- * that does in_interrupt()
- */
+ /* Set up %gs.
+ *
+ * On SMP, %gs should point to the per-cpu area. For initial
+ * boot, make %gs point to the init data section. For a
+ * secondary CPU,initial_gs should be set to its pda address
+ * before the CPU runs this code.
+ *
+ * On UP, initial_gs points to PER_CPU_VAR(__pda) and doesn't
+ * change.
+ */
movl $MSR_GS_BASE,%ecx
- movq $empty_zero_page,%rax
+ movq initial_gs(%rip),%rax
movq %rax,%rdx
shrq $32,%rdx
wrmsr
@@ -257,6 +281,12 @@ ENTRY(secondary_startup_64)
.align 8
ENTRY(initial_code)
.quad x86_64_start_kernel
+ ENTRY(initial_gs)
+#ifdef CONFIG_SMP
+ .quad __per_cpu_load
+#else
+ .quad PER_CPU_VAR(__pda)
+#endif
__FINITDATA
ENTRY(stack_start)
@@ -401,7 +431,12 @@ NEXT_PAGE(level2_spare_pgt)
.globl early_gdt_descr
early_gdt_descr:
.word GDT_ENTRIES*8-1
- .quad per_cpu__gdt_page
+#ifdef CONFIG_SMP
+early_gdt_descr_base:
+ .quad 0x0000000000000000
+#else
+ .quad per_cpu__gdt_page
+#endif
ENTRY(phys_base)
/* This must match the first entry in level2_kernel_pgt */
diff --git a/arch/x86/kernel/io_apic.c b/arch/x86/kernel/io_apic.c
index 1c4a130..f796603 100644
--- a/arch/x86/kernel/io_apic.c
+++ b/arch/x86/kernel/io_apic.c
@@ -46,6 +46,7 @@
#include <asm/idle.h>
#include <asm/io.h>
#include <asm/smp.h>
+#include <asm/cpu.h>
#include <asm/desc.h>
#include <asm/proto.h>
#include <asm/acpi.h>
@@ -82,11 +83,11 @@ static DEFINE_SPINLOCK(vector_lock);
int nr_ioapic_registers[MAX_IO_APICS];
/* I/O APIC entries */
-struct mp_config_ioapic mp_ioapics[MAX_IO_APICS];
+struct mpc_ioapic mp_ioapics[MAX_IO_APICS];
int nr_ioapics;
/* MP IRQ source entries */
-struct mp_config_intsrc mp_irqs[MAX_IRQ_SOURCES];
+struct mpc_intsrc mp_irqs[MAX_IRQ_SOURCES];
/* # of MP IRQ source entries */
int mp_irq_entries;
@@ -356,7 +357,7 @@ set_extra_move_desc(struct irq_desc *desc, const struct cpumask *mask)
if (!cfg->move_in_progress) {
/* it means that domain is not changed */
- if (!cpumask_intersects(&desc->affinity, mask))
+ if (!cpumask_intersects(desc->affinity, mask))
cfg->move_desc_pending = 1;
}
}
@@ -386,7 +387,7 @@ struct io_apic {
static __attribute_const__ struct io_apic __iomem *io_apic_base(int idx)
{
return (void __iomem *) __fix_to_virt(FIX_IO_APIC_BASE_0 + idx)
- + (mp_ioapics[idx].mp_apicaddr & ~PAGE_MASK);
+ + (mp_ioapics[idx].apicaddr & ~PAGE_MASK);
}
static inline unsigned int io_apic_read(unsigned int apic, unsigned int reg)
@@ -579,9 +580,9 @@ set_desc_affinity(struct irq_desc *desc, const struct cpumask *mask)
if (assign_irq_vector(irq, cfg, mask))
return BAD_APICID;
- cpumask_and(&desc->affinity, cfg->domain, mask);
+ cpumask_and(desc->affinity, cfg->domain, mask);
set_extra_move_desc(desc, mask);
- return cpu_mask_to_apicid_and(&desc->affinity, cpu_online_mask);
+ return cpu_mask_to_apicid_and(desc->affinity, cpu_online_mask);
}
static void
@@ -944,10 +945,10 @@ static int find_irq_entry(int apic, int pin, int type)
int i;
for (i = 0; i < mp_irq_entries; i++)
- if (mp_irqs[i].mp_irqtype == type &&
- (mp_irqs[i].mp_dstapic == mp_ioapics[apic].mp_apicid ||
- mp_irqs[i].mp_dstapic == MP_APIC_ALL) &&
- mp_irqs[i].mp_dstirq == pin)
+ if (mp_irqs[i].irqtype == type &&
+ (mp_irqs[i].dstapic == mp_ioapics[apic].apicid ||
+ mp_irqs[i].dstapic == MP_APIC_ALL) &&
+ mp_irqs[i].dstirq == pin)
return i;
return -1;
@@ -961,13 +962,13 @@ static int __init find_isa_irq_pin(int irq, int type)
int i;
for (i = 0; i < mp_irq_entries; i++) {
- int lbus = mp_irqs[i].mp_srcbus;
+ int lbus = mp_irqs[i].srcbus;
if (test_bit(lbus, mp_bus_not_pci) &&
- (mp_irqs[i].mp_irqtype == type) &&
- (mp_irqs[i].mp_srcbusirq == irq))
+ (mp_irqs[i].irqtype == type) &&
+ (mp_irqs[i].srcbusirq == irq))
- return mp_irqs[i].mp_dstirq;
+ return mp_irqs[i].dstirq;
}
return -1;
}
@@ -977,17 +978,17 @@ 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].mp_srcbus;
+ int lbus = mp_irqs[i].srcbus;
if (test_bit(lbus, mp_bus_not_pci) &&
- (mp_irqs[i].mp_irqtype == type) &&
- (mp_irqs[i].mp_srcbusirq == irq))
+ (mp_irqs[i].irqtype == type) &&
+ (mp_irqs[i].srcbusirq == irq))
break;
}
if (i < mp_irq_entries) {
int apic;
for(apic = 0; apic < nr_ioapics; apic++) {
- if (mp_ioapics[apic].mp_apicid == mp_irqs[i].mp_dstapic)
+ if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic)
return apic;
}
}
@@ -1012,23 +1013,23 @@ int IO_APIC_get_PCI_irq_vector(int bus, int slot, int pin)
return -1;
}
for (i = 0; i < mp_irq_entries; i++) {
- int lbus = mp_irqs[i].mp_srcbus;
+ int lbus = mp_irqs[i].srcbus;
for (apic = 0; apic < nr_ioapics; apic++)
- if (mp_ioapics[apic].mp_apicid == mp_irqs[i].mp_dstapic ||
- mp_irqs[i].mp_dstapic == MP_APIC_ALL)
+ if (mp_ioapics[apic].apicid == mp_irqs[i].dstapic ||
+ mp_irqs[i].dstapic == MP_APIC_ALL)
break;
if (!test_bit(lbus, mp_bus_not_pci) &&
- !mp_irqs[i].mp_irqtype &&
+ !mp_irqs[i].irqtype &&
(bus == lbus) &&
- (slot == ((mp_irqs[i].mp_srcbusirq >> 2) & 0x1f))) {
- int irq = pin_2_irq(i,apic,mp_irqs[i].mp_dstirq);
+ (slot == ((mp_irqs[i].srcbusirq >> 2) & 0x1f))) {
+ int irq = pin_2_irq(i, apic, mp_irqs[i].dstirq);
if (!(apic || IO_APIC_IRQ(irq)))
continue;
- if (pin == (mp_irqs[i].mp_srcbusirq & 3))
+ if (pin == (mp_irqs[i].srcbusirq & 3))
return irq;
/*
* Use the first all-but-pin matching entry as a
@@ -1071,7 +1072,7 @@ static int EISA_ELCR(unsigned int irq)
* EISA conforming in the MP table, that means its trigger type must
* be read in from the ELCR */
-#define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].mp_srcbusirq))
+#define default_EISA_trigger(idx) (EISA_ELCR(mp_irqs[idx].srcbusirq))
#define default_EISA_polarity(idx) default_ISA_polarity(idx)
/* PCI interrupts are always polarity one level triggered,
@@ -1088,13 +1089,13 @@ static int EISA_ELCR(unsigned int irq)
static int MPBIOS_polarity(int idx)
{
- int bus = mp_irqs[idx].mp_srcbus;
+ int bus = mp_irqs[idx].srcbus;
int polarity;
/*
* Determine IRQ line polarity (high active or low active):
*/
- switch (mp_irqs[idx].mp_irqflag & 3)
+ switch (mp_irqs[idx].irqflag & 3)
{
case 0: /* conforms, ie. bus-type dependent polarity */
if (test_bit(bus, mp_bus_not_pci))
@@ -1130,13 +1131,13 @@ static int MPBIOS_polarity(int idx)
static int MPBIOS_trigger(int idx)
{
- int bus = mp_irqs[idx].mp_srcbus;
+ int bus = mp_irqs[idx].srcbus;
int trigger;
/*
* Determine IRQ trigger mode (edge or level sensitive):
*/
- switch ((mp_irqs[idx].mp_irqflag>>2) & 3)
+ switch ((mp_irqs[idx].irqflag>>2) & 3)
{
case 0: /* conforms, ie. bus-type dependent */
if (test_bit(bus, mp_bus_not_pci))
@@ -1214,16 +1215,16 @@ int (*ioapic_renumber_irq)(int ioapic, int irq);
static int pin_2_irq(int idx, int apic, int pin)
{
int irq, i;
- int bus = mp_irqs[idx].mp_srcbus;
+ int bus = mp_irqs[idx].srcbus;
/*
* Debugging check, we are in big trouble if this message pops up!
*/
- if (mp_irqs[idx].mp_dstirq != pin)
+ if (mp_irqs[idx].dstirq != pin)
printk(KERN_ERR "broken BIOS or MPTABLE parser, ayiee!!\n");
if (test_bit(bus, mp_bus_not_pci)) {
- irq = mp_irqs[idx].mp_srcbusirq;
+ irq = mp_irqs[idx].srcbusirq;
} else {
/*
* PCI IRQs are mapped in order
@@ -1566,14 +1567,14 @@ static void setup_IO_APIC_irq(int apic, int pin, unsigned int irq, struct irq_de
apic_printk(APIC_VERBOSE,KERN_DEBUG
"IOAPIC[%d]: Set routing entry (%d-%d -> 0x%x -> "
"IRQ %d Mode:%i Active:%i)\n",
- apic, mp_ioapics[apic].mp_apicid, pin, cfg->vector,
+ apic, mp_ioapics[apic].apicid, pin, cfg->vector,
irq, trigger, polarity);
- if (setup_ioapic_entry(mp_ioapics[apic].mp_apicid, irq, &entry,
+ if (setup_ioapic_entry(mp_ioapics[apic].apicid, irq, &entry,
dest, trigger, polarity, cfg->vector)) {
printk("Failed to setup ioapic entry for ioapic %d, pin %d\n",
- mp_ioapics[apic].mp_apicid, pin);
+ mp_ioapics[apic].apicid, pin);
__clear_irq_vector(irq, cfg);
return;
}
@@ -1604,12 +1605,10 @@ static void __init setup_IO_APIC_irqs(void)
notcon = 1;
apic_printk(APIC_VERBOSE,
KERN_DEBUG " %d-%d",
- mp_ioapics[apic].mp_apicid,
- pin);
+ mp_ioapics[apic].apicid, pin);
} else
apic_printk(APIC_VERBOSE, " %d-%d",
- mp_ioapics[apic].mp_apicid,
- pin);
+ mp_ioapics[apic].apicid, pin);
continue;
}
if (notcon) {
@@ -1699,7 +1698,7 @@ __apicdebuginit(void) print_IO_APIC(void)
printk(KERN_DEBUG "number of MP IRQ sources: %d.\n", mp_irq_entries);
for (i = 0; i < nr_ioapics; i++)
printk(KERN_DEBUG "number of IO-APIC #%d registers: %d.\n",
- mp_ioapics[i].mp_apicid, nr_ioapic_registers[i]);
+ mp_ioapics[i].apicid, nr_ioapic_registers[i]);
/*
* We are a bit conservative about what we expect. We have to
@@ -1719,7 +1718,7 @@ __apicdebuginit(void) print_IO_APIC(void)
spin_unlock_irqrestore(&ioapic_lock, flags);
printk("\n");
- printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].mp_apicid);
+ printk(KERN_DEBUG "IO APIC #%d......\n", mp_ioapics[apic].apicid);
printk(KERN_DEBUG ".... register #00: %08X\n", reg_00.raw);
printk(KERN_DEBUG "....... : physical APIC id: %02X\n", reg_00.bits.ID);
printk(KERN_DEBUG "....... : Delivery Type: %X\n", reg_00.bits.delivery_type);
@@ -2121,14 +2120,14 @@ static void __init setup_ioapic_ids_from_mpc(void)
reg_00.raw = io_apic_read(apic, 0);
spin_unlock_irqrestore(&ioapic_lock, flags);
- old_id = mp_ioapics[apic].mp_apicid;
+ old_id = mp_ioapics[apic].apicid;
- if (mp_ioapics[apic].mp_apicid >= get_physical_broadcast()) {
+ if (mp_ioapics[apic].apicid >= get_physical_broadcast()) {
printk(KERN_ERR "BIOS bug, IO-APIC#%d ID is %d in the MPC table!...\n",
- apic, mp_ioapics[apic].mp_apicid);
+ apic, mp_ioapics[apic].apicid);
printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
reg_00.bits.ID);
- mp_ioapics[apic].mp_apicid = reg_00.bits.ID;
+ mp_ioapics[apic].apicid = reg_00.bits.ID;
}
/*
@@ -2137,9 +2136,9 @@ static void __init setup_ioapic_ids_from_mpc(void)
* 'stuck on smp_invalidate_needed IPI wait' messages.
*/
if (check_apicid_used(phys_id_present_map,
- mp_ioapics[apic].mp_apicid)) {
+ mp_ioapics[apic].apicid)) {
printk(KERN_ERR "BIOS bug, IO-APIC#%d ID %d is already used!...\n",
- apic, mp_ioapics[apic].mp_apicid);
+ apic, mp_ioapics[apic].apicid);
for (i = 0; i < get_physical_broadcast(); i++)
if (!physid_isset(i, phys_id_present_map))
break;
@@ -2148,13 +2147,13 @@ static void __init setup_ioapic_ids_from_mpc(void)
printk(KERN_ERR "... fixing up to %d. (tell your hw vendor)\n",
i);
physid_set(i, phys_id_present_map);
- mp_ioapics[apic].mp_apicid = i;
+ mp_ioapics[apic].apicid = i;
} else {
physid_mask_t tmp;
- tmp = apicid_to_cpu_present(mp_ioapics[apic].mp_apicid);
+ tmp = apicid_to_cpu_present(mp_ioapics[apic].apicid);
apic_printk(APIC_VERBOSE, "Setting %d in the "
"phys_id_present_map\n",
- mp_ioapics[apic].mp_apicid);
+ mp_ioapics[apic].apicid);
physids_or(phys_id_present_map, phys_id_present_map, tmp);
}
@@ -2163,11 +2162,11 @@ static void __init setup_ioapic_ids_from_mpc(void)
* We need to adjust the IRQ routing table
* if the ID changed.
*/
- if (old_id != mp_ioapics[apic].mp_apicid)
+ if (old_id != mp_ioapics[apic].apicid)
for (i = 0; i < mp_irq_entries; i++)
- if (mp_irqs[i].mp_dstapic == old_id)
- mp_irqs[i].mp_dstapic
- = mp_ioapics[apic].mp_apicid;
+ if (mp_irqs[i].dstapic == old_id)
+ mp_irqs[i].dstapic
+ = mp_ioapics[apic].apicid;
/*
* Read the right value from the MPC table and
@@ -2175,9 +2174,9 @@ static void __init setup_ioapic_ids_from_mpc(void)
*/
apic_printk(APIC_VERBOSE, KERN_INFO
"...changing IO-APIC physical APIC ID to %d ...",
- mp_ioapics[apic].mp_apicid);
+ mp_ioapics[apic].apicid);
- reg_00.bits.ID = mp_ioapics[apic].mp_apicid;
+ reg_00.bits.ID = mp_ioapics[apic].apicid;
spin_lock_irqsave(&ioapic_lock, flags);
io_apic_write(apic, 0, reg_00.raw);
spin_unlock_irqrestore(&ioapic_lock, flags);
@@ -2188,7 +2187,7 @@ static void __init setup_ioapic_ids_from_mpc(void)
spin_lock_irqsave(&ioapic_lock, flags);
reg_00.raw = io_apic_read(apic, 0);
spin_unlock_irqrestore(&ioapic_lock, flags);
- if (reg_00.bits.ID != mp_ioapics[apic].mp_apicid)
+ if (reg_00.bits.ID != mp_ioapics[apic].apicid)
printk("could not set ID!\n");
else
apic_printk(APIC_VERBOSE, " ok.\n");
@@ -2383,7 +2382,7 @@ migrate_ioapic_irq_desc(struct irq_desc *desc, const struct cpumask *mask)
if (cfg->move_in_progress)
send_cleanup_vector(cfg);
- cpumask_copy(&desc->affinity, mask);
+ cpumask_copy(desc->affinity, mask);
}
static int migrate_irq_remapped_level_desc(struct irq_desc *desc)
@@ -2405,11 +2404,11 @@ static int migrate_irq_remapped_level_desc(struct irq_desc *desc)
}
/* everthing is clear. we have right of way */
- migrate_ioapic_irq_desc(desc, &desc->pending_mask);
+ migrate_ioapic_irq_desc(desc, desc->pending_mask);
ret = 0;
desc->status &= ~IRQ_MOVE_PENDING;
- cpumask_clear(&desc->pending_mask);
+ cpumask_clear(desc->pending_mask);
unmask:
unmask_IO_APIC_irq_desc(desc);
@@ -2434,7 +2433,7 @@ static void ir_irq_migration(struct work_struct *work)
continue;
}
- desc->chip->set_affinity(irq, &desc->pending_mask);
+ desc->chip->set_affinity(irq, desc->pending_mask);
spin_unlock_irqrestore(&desc->lock, flags);
}
}
@@ -2448,7 +2447,7 @@ static void set_ir_ioapic_affinity_irq_desc(struct irq_desc *desc,
{
if (desc->status & IRQ_LEVEL) {
desc->status |= IRQ_MOVE_PENDING;
- cpumask_copy(&desc->pending_mask, mask);
+ cpumask_copy(desc->pending_mask, mask);
migrate_irq_remapped_level_desc(desc);
return;
}
@@ -2516,7 +2515,7 @@ static void irq_complete_move(struct irq_desc **descp)
/* domain has not changed, but affinity did */
me = smp_processor_id();
- if (cpu_isset(me, desc->affinity)) {
+ if (cpumask_test_cpu(me, desc->affinity)) {
*descp = desc = move_irq_desc(desc, me);
/* get the new one */
cfg = desc->chip_data;
@@ -3117,8 +3116,8 @@ static int ioapic_resume(struct sys_device *dev)
spin_lock_irqsave(&ioapic_lock, flags);
reg_00.raw = io_apic_read(dev->id, 0);
- if (reg_00.bits.ID != mp_ioapics[dev->id].mp_apicid) {
- reg_00.bits.ID = mp_ioapics[dev->id].mp_apicid;
+ if (reg_00.bits.ID != mp_ioapics[dev->id].apicid) {
+ reg_00.bits.ID = mp_ioapics[dev->id].apicid;
io_apic_write(dev->id, 0, reg_00.raw);
}
spin_unlock_irqrestore(&ioapic_lock, flags);
@@ -3183,7 +3182,7 @@ unsigned int create_irq_nr(unsigned int irq_want)
irq = 0;
spin_lock_irqsave(&vector_lock, flags);
- for (new = irq_want; new < NR_IRQS; new++) {
+ for (new = irq_want; new < nr_irqs; new++) {
if (platform_legacy_irq(new))
continue;
@@ -3258,6 +3257,9 @@ static int msi_compose_msg(struct pci_dev *pdev, unsigned int irq, struct msi_ms
int err;
unsigned dest;
+ if (disable_apic)
+ return -ENXIO;
+
cfg = irq_cfg(irq);
err = assign_irq_vector(irq, cfg, TARGET_CPUS);
if (err)
@@ -3726,6 +3728,9 @@ int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
struct irq_cfg *cfg;
int err;
+ if (disable_apic)
+ return -ENXIO;
+
cfg = irq_cfg(irq);
err = assign_irq_vector(irq, cfg, TARGET_CPUS);
if (!err) {
@@ -3850,6 +3855,22 @@ void __init probe_nr_irqs_gsi(void)
nr_irqs_gsi = nr;
}
+#ifdef CONFIG_SPARSE_IRQ
+int __init arch_probe_nr_irqs(void)
+{
+ int nr;
+
+ nr = ((8 * nr_cpu_ids) > (32 * nr_ioapics) ?
+ (NR_VECTORS + (8 * nr_cpu_ids)) :
+ (NR_VECTORS + (32 * nr_ioapics)));
+
+ if (nr < nr_irqs && nr > nr_irqs_gsi)
+ nr_irqs = nr;
+
+ return 0;
+}
+#endif
+
/* --------------------------------------------------------------------------
ACPI-based IOAPIC Configuration
-------------------------------------------------------------------------- */
@@ -3984,8 +4005,8 @@ int acpi_get_override_irq(int bus_irq, int *trigger, int *polarity)
return -1;
for (i = 0; i < mp_irq_entries; i++)
- if (mp_irqs[i].mp_irqtype == mp_INT &&
- mp_irqs[i].mp_srcbusirq == bus_irq)
+ if (mp_irqs[i].irqtype == mp_INT &&
+ mp_irqs[i].srcbusirq == bus_irq)
break;
if (i >= mp_irq_entries)
return -1;
@@ -4039,7 +4060,7 @@ void __init setup_ioapic_dest(void)
*/
if (desc->status &
(IRQ_NO_BALANCING | IRQ_AFFINITY_SET))
- mask = &desc->affinity;
+ mask = desc->affinity;
else
mask = TARGET_CPUS;
@@ -4100,7 +4121,7 @@ void __init ioapic_init_mappings(void)
ioapic_res = ioapic_setup_resources();
for (i = 0; i < nr_ioapics; i++) {
if (smp_found_config) {
- ioapic_phys = mp_ioapics[i].mp_apicaddr;
+ ioapic_phys = mp_ioapics[i].apicaddr;
#ifdef CONFIG_X86_32
if (!ioapic_phys) {
printk(KERN_ERR
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c
index 22f650d..a6bca1d 100644
--- a/arch/x86/kernel/irq.c
+++ b/arch/x86/kernel/irq.c
@@ -36,11 +36,7 @@ void ack_bad_irq(unsigned int irq)
#endif
}
-#ifdef CONFIG_X86_32
-# define irq_stats(x) (&per_cpu(irq_stat, x))
-#else
-# define irq_stats(x) cpu_pda(x)
-#endif
+#define irq_stats(x) (&per_cpu(irq_stat, x))
/*
* /proc/interrupts printing:
*/
diff --git a/arch/x86/kernel/irq_32.c b/arch/x86/kernel/irq_32.c
index 74b9ff7..e0f29be 100644
--- a/arch/x86/kernel/irq_32.c
+++ b/arch/x86/kernel/irq_32.c
@@ -248,7 +248,7 @@ void fixup_irqs(void)
if (irq == 2)
continue;
- affinity = &desc->affinity;
+ affinity = desc->affinity;
if (cpumask_any_and(affinity, cpu_online_mask) >= nr_cpu_ids) {
printk("Breaking affinity for irq %i\n", irq);
affinity = cpu_all_mask;
diff --git a/arch/x86/kernel/irq_64.c b/arch/x86/kernel/irq_64.c
index 63c88e6..1db0524 100644
--- a/arch/x86/kernel/irq_64.c
+++ b/arch/x86/kernel/irq_64.c
@@ -19,6 +19,9 @@
#include <asm/io_apic.h>
#include <asm/idle.h>
+DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat);
+EXPORT_PER_CPU_SYMBOL(irq_stat);
+
/*
* Probabilistic stack overflow check:
*
@@ -100,7 +103,7 @@ void fixup_irqs(void)
/* interrupt's are disabled at this point */
spin_lock(&desc->lock);
- affinity = &desc->affinity;
+ affinity = desc->affinity;
if (!irq_has_action(irq) ||
cpumask_equal(affinity, cpu_online_mask)) {
spin_unlock(&desc->lock);
diff --git a/arch/x86/kernel/microcode_intel.c b/arch/x86/kernel/microcode_intel.c
index b7f4c92..5e9f4fc 100644
--- a/arch/x86/kernel/microcode_intel.c
+++ b/arch/x86/kernel/microcode_intel.c
@@ -87,9 +87,9 @@
#include <linux/cpu.h>
#include <linux/firmware.h>
#include <linux/platform_device.h>
+#include <linux/uaccess.h>
#include <asm/msr.h>
-#include <asm/uaccess.h>
#include <asm/processor.h>
#include <asm/microcode.h>
@@ -196,7 +196,7 @@ static inline int update_match_cpu(struct cpu_signature *csig, int sig, int pf)
return (!sigmatch(sig, csig->sig, pf, csig->pf)) ? 0 : 1;
}
-static inline int
+static inline int
update_match_revision(struct microcode_header_intel *mc_header, int rev)
{
return (mc_header->rev <= rev) ? 0 : 1;
@@ -442,8 +442,8 @@ static int request_microcode_fw(int cpu, struct device *device)
return ret;
}
- ret = generic_load_microcode(cpu, (void*)firmware->data, firmware->size,
- &get_ucode_fw);
+ ret = generic_load_microcode(cpu, (void *)firmware->data,
+ firmware->size, &get_ucode_fw);
release_firmware(firmware);
@@ -460,7 +460,7 @@ static int request_microcode_user(int cpu, const void __user *buf, size_t size)
/* We should bind the task to the CPU */
BUG_ON(cpu != raw_smp_processor_id());
- return generic_load_microcode(cpu, (void*)buf, size, &get_ucode_user);
+ return generic_load_microcode(cpu, (void *)buf, size, &get_ucode_user);
}
static void microcode_fini_cpu(int cpu)
diff --git a/arch/x86/kernel/module_32.c b/arch/x86/kernel/module_32.c
index 3db0a544..0edd819 100644
--- a/arch/x86/kernel/module_32.c
+++ b/arch/x86/kernel/module_32.c
@@ -42,7 +42,7 @@ void module_free(struct module *mod, void *module_region)
{
vfree(module_region);
/* FIXME: If module_region == mod->init_region, trim exception
- table entries. */
+ table entries. */
}
/* We don't need anything special. */
@@ -113,13 +113,13 @@ int module_finalize(const Elf_Ehdr *hdr,
*para = NULL;
char *secstrings = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
- for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
+ for (s = sechdrs; s < sechdrs + hdr->e_shnum; s++) {
if (!strcmp(".text", secstrings + s->sh_name))
text = s;
if (!strcmp(".altinstructions", secstrings + s->sh_name))
alt = s;
if (!strcmp(".smp_locks", secstrings + s->sh_name))
- locks= s;
+ locks = s;
if (!strcmp(".parainstructions", secstrings + s->sh_name))
para = s;
}
diff --git a/arch/x86/kernel/module_64.c b/arch/x86/kernel/module_64.c
index 6ba8783..c23880b 100644
--- a/arch/x86/kernel/module_64.c
+++ b/arch/x86/kernel/module_64.c
@@ -30,14 +30,14 @@
#include <asm/page.h>
#include <asm/pgtable.h>
-#define DEBUGP(fmt...)
+#define DEBUGP(fmt...)
#ifndef CONFIG_UML
void module_free(struct module *mod, void *module_region)
{
vfree(module_region);
/* FIXME: If module_region == mod->init_region, trim exception
- table entries. */
+ table entries. */
}
void *module_alloc(unsigned long size)
@@ -77,7 +77,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
Elf64_Rela *rel = (void *)sechdrs[relsec].sh_addr;
Elf64_Sym *sym;
void *loc;
- u64 val;
+ u64 val;
DEBUGP("Applying relocate section %u to %u\n", relsec,
sechdrs[relsec].sh_info);
@@ -91,11 +91,11 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
sym = (Elf64_Sym *)sechdrs[symindex].sh_addr
+ ELF64_R_SYM(rel[i].r_info);
- DEBUGP("type %d st_value %Lx r_addend %Lx loc %Lx\n",
- (int)ELF64_R_TYPE(rel[i].r_info),
- sym->st_value, rel[i].r_addend, (u64)loc);
+ DEBUGP("type %d st_value %Lx r_addend %Lx loc %Lx\n",
+ (int)ELF64_R_TYPE(rel[i].r_info),
+ sym->st_value, rel[i].r_addend, (u64)loc);
- val = sym->st_value + rel[i].r_addend;
+ val = sym->st_value + rel[i].r_addend;
switch (ELF64_R_TYPE(rel[i].r_info)) {
case R_X86_64_NONE:
@@ -113,16 +113,16 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
if ((s64)val != *(s32 *)loc)
goto overflow;
break;
- case R_X86_64_PC32:
+ case R_X86_64_PC32:
val -= (u64)loc;
*(u32 *)loc = val;
#if 0
if ((s64)val != *(s32 *)loc)
- goto overflow;
+ goto overflow;
#endif
break;
default:
- printk(KERN_ERR "module %s: Unknown rela relocation: %Lu\n",
+ printk(KERN_ERR "module %s: Unknown rela relocation: %llu\n",
me->name, ELF64_R_TYPE(rel[i].r_info));
return -ENOEXEC;
}
@@ -130,7 +130,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs,
return 0;
overflow:
- printk(KERN_ERR "overflow in relocation type %d val %Lx\n",
+ printk(KERN_ERR "overflow in relocation type %d val %Lx\n",
(int)ELF64_R_TYPE(rel[i].r_info), val);
printk(KERN_ERR "`%s' likely not compiled with -mcmodel=kernel\n",
me->name);
@@ -143,13 +143,13 @@ int apply_relocate(Elf_Shdr *sechdrs,
unsigned int relsec,
struct module *me)
{
- printk("non add relocation not supported\n");
+ printk(KERN_ERR "non add relocation not supported\n");
return -ENOSYS;
-}
+}
int module_finalize(const Elf_Ehdr *hdr,
- const Elf_Shdr *sechdrs,
- struct module *me)
+ const Elf_Shdr *sechdrs,
+ struct module *me)
{
const Elf_Shdr *s, *text = NULL, *alt = NULL, *locks = NULL,
*para = NULL;
@@ -161,7 +161,7 @@ int module_finalize(const Elf_Ehdr *hdr,
if (!strcmp(".altinstructions", secstrings + s->sh_name))
alt = s;
if (!strcmp(".smp_locks", secstrings + s->sh_name))
- locks= s;
+ locks = s;
if (!strcmp(".parainstructions", secstrings + s->sh_name))
para = s;
}
diff --git a/arch/x86/kernel/mpparse.c b/arch/x86/kernel/mpparse.c
index c0601c2..fa6bb26 100644
--- a/arch/x86/kernel/mpparse.c
+++ b/arch/x86/kernel/mpparse.c
@@ -27,6 +27,7 @@
#include <asm/e820.h>
#include <asm/trampoline.h>
#include <asm/setup.h>
+#include <asm/smp.h>
#include <mach_apic.h>
#ifdef CONFIG_X86_32
@@ -143,11 +144,11 @@ static void __init MP_ioapic_info(struct mpc_ioapic *m)
if (bad_ioapic(m->apicaddr))
return;
- mp_ioapics[nr_ioapics].mp_apicaddr = m->apicaddr;
- mp_ioapics[nr_ioapics].mp_apicid = m->apicid;
- mp_ioapics[nr_ioapics].mp_type = m->type;
- mp_ioapics[nr_ioapics].mp_apicver = m->apicver;
- mp_ioapics[nr_ioapics].mp_flags = m->flags;
+ mp_ioapics[nr_ioapics].apicaddr = m->apicaddr;
+ mp_ioapics[nr_ioapics].apicid = m->apicid;
+ mp_ioapics[nr_ioapics].type = m->type;
+ mp_ioapics[nr_ioapics].apicver = m->apicver;
+ mp_ioapics[nr_ioapics].flags = m->flags;
nr_ioapics++;
}
@@ -159,55 +160,55 @@ static void print_MP_intsrc_info(struct mpc_intsrc *m)
m->srcbusirq, m->dstapic, m->dstirq);
}
-static void __init print_mp_irq_info(struct mp_config_intsrc *mp_irq)
+static void __init print_mp_irq_info(struct mpc_intsrc *mp_irq)
{
apic_printk(APIC_VERBOSE, "Int: type %d, pol %d, trig %d, bus %02x,"
" IRQ %02x, APIC ID %x, APIC INT %02x\n",
- mp_irq->mp_irqtype, mp_irq->mp_irqflag & 3,
- (mp_irq->mp_irqflag >> 2) & 3, mp_irq->mp_srcbus,
- mp_irq->mp_srcbusirq, mp_irq->mp_dstapic, mp_irq->mp_dstirq);
+ mp_irq->irqtype, mp_irq->irqflag & 3,
+ (mp_irq->irqflag >> 2) & 3, mp_irq->srcbus,
+ mp_irq->srcbusirq, mp_irq->dstapic, mp_irq->dstirq);
}
static void __init assign_to_mp_irq(struct mpc_intsrc *m,
- struct mp_config_intsrc *mp_irq)
+ struct mpc_intsrc *mp_irq)
{
- mp_irq->mp_dstapic = m->dstapic;
- mp_irq->mp_type = m->type;
- mp_irq->mp_irqtype = m->irqtype;
- mp_irq->mp_irqflag = m->irqflag;
- mp_irq->mp_srcbus = m->srcbus;
- mp_irq->mp_srcbusirq = m->srcbusirq;
- mp_irq->mp_dstirq = m->dstirq;
+ mp_irq->dstapic = m->dstapic;
+ mp_irq->type = m->type;
+ mp_irq->irqtype = m->irqtype;
+ mp_irq->irqflag = m->irqflag;
+ mp_irq->srcbus = m->srcbus;
+ mp_irq->srcbusirq = m->srcbusirq;
+ mp_irq->dstirq = m->dstirq;
}
-static void __init assign_to_mpc_intsrc(struct mp_config_intsrc *mp_irq,
+static void __init assign_to_mpc_intsrc(struct mpc_intsrc *mp_irq,
struct mpc_intsrc *m)
{
- m->dstapic = mp_irq->mp_dstapic;
- m->type = mp_irq->mp_type;
- m->irqtype = mp_irq->mp_irqtype;
- m->irqflag = mp_irq->mp_irqflag;
- m->srcbus = mp_irq->mp_srcbus;
- m->srcbusirq = mp_irq->mp_srcbusirq;
- m->dstirq = mp_irq->mp_dstirq;
+ m->dstapic = mp_irq->dstapic;
+ m->type = mp_irq->type;
+ m->irqtype = mp_irq->irqtype;
+ m->irqflag = mp_irq->irqflag;
+ m->srcbus = mp_irq->srcbus;
+ m->srcbusirq = mp_irq->srcbusirq;
+ m->dstirq = mp_irq->dstirq;
}
-static int __init mp_irq_mpc_intsrc_cmp(struct mp_config_intsrc *mp_irq,
+static int __init mp_irq_mpc_intsrc_cmp(struct mpc_intsrc *mp_irq,
struct mpc_intsrc *m)
{
- if (mp_irq->mp_dstapic != m->dstapic)
+ if (mp_irq->dstapic != m->dstapic)
return 1;
- if (mp_irq->mp_type != m->type)
+ if (mp_irq->type != m->type)
return 2;
- if (mp_irq->mp_irqtype != m->irqtype)
+ if (mp_irq->irqtype != m->irqtype)
return 3;
- if (mp_irq->mp_irqflag != m->irqflag)
+ if (mp_irq->irqflag != m->irqflag)
return 4;
- if (mp_irq->mp_srcbus != m->srcbus)
+ if (mp_irq->srcbus != m->srcbus)
return 5;
- if (mp_irq->mp_srcbusirq != m->srcbusirq)
+ if (mp_irq->srcbusirq != m->srcbusirq)
return 6;
- if (mp_irq->mp_dstirq != m->dstirq)
+ if (mp_irq->dstirq != m->dstirq)
return 7;
return 0;
@@ -416,7 +417,7 @@ static void __init construct_default_ioirq_mptable(int mpc_default_type)
intsrc.type = MP_INTSRC;
intsrc.irqflag = 0; /* conforming */
intsrc.srcbus = 0;
- intsrc.dstapic = mp_ioapics[0].mp_apicid;
+ intsrc.dstapic = mp_ioapics[0].apicid;
intsrc.irqtype = mp_INT;
@@ -569,14 +570,14 @@ static inline void __init construct_default_ISA_mptable(int mpc_default_type)
}
}
-static struct intel_mp_floating *mpf_found;
+static struct mpf_intel *mpf_found;
/*
* Scan the memory blocks for an SMP configuration block.
*/
static void __init __get_smp_config(unsigned int early)
{
- struct intel_mp_floating *mpf = mpf_found;
+ struct mpf_intel *mpf = mpf_found;
if (!mpf)
return;
@@ -597,9 +598,9 @@ static void __init __get_smp_config(unsigned int early)
}
printk(KERN_INFO "Intel MultiProcessor Specification v1.%d\n",
- mpf->mpf_specification);
+ mpf->specification);
#if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32)
- if (mpf->mpf_feature2 & (1 << 7)) {
+ if (mpf->feature2 & (1 << 7)) {
printk(KERN_INFO " IMCR and PIC compatibility mode.\n");
pic_mode = 1;
} else {
@@ -610,7 +611,7 @@ static void __init __get_smp_config(unsigned int early)
/*
* Now see if we need to read further.
*/
- if (mpf->mpf_feature1 != 0) {
+ if (mpf->feature1 != 0) {
if (early) {
/*
* local APIC has default address
@@ -620,16 +621,16 @@ static void __init __get_smp_config(unsigned int early)
}
printk(KERN_INFO "Default MP configuration #%d\n",
- mpf->mpf_feature1);
- construct_default_ISA_mptable(mpf->mpf_feature1);
+ mpf->feature1);
+ construct_default_ISA_mptable(mpf->feature1);
- } else if (mpf->mpf_physptr) {
+ } else if (mpf->physptr) {
/*
* Read the physical hardware table. Anything here will
* override the defaults.
*/
- if (!smp_read_mpc(phys_to_virt(mpf->mpf_physptr), early)) {
+ if (!smp_read_mpc(phys_to_virt(mpf->physptr), early)) {
#ifdef CONFIG_X86_LOCAL_APIC
smp_found_config = 0;
#endif
@@ -687,19 +688,19 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
unsigned reserve)
{
unsigned int *bp = phys_to_virt(base);
- struct intel_mp_floating *mpf;
+ struct mpf_intel *mpf;
apic_printk(APIC_VERBOSE, "Scan SMP from %p for %ld bytes.\n",
bp, length);
BUILD_BUG_ON(sizeof(*mpf) != 16);
while (length > 0) {
- mpf = (struct intel_mp_floating *)bp;
+ mpf = (struct mpf_intel *)bp;
if ((*bp == SMP_MAGIC_IDENT) &&
- (mpf->mpf_length == 1) &&
+ (mpf->length == 1) &&
!mpf_checksum((unsigned char *)bp, 16) &&
- ((mpf->mpf_specification == 1)
- || (mpf->mpf_specification == 4))) {
+ ((mpf->specification == 1)
+ || (mpf->specification == 4))) {
#ifdef CONFIG_X86_LOCAL_APIC
smp_found_config = 1;
#endif
@@ -712,7 +713,7 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
return 1;
reserve_bootmem_generic(virt_to_phys(mpf), PAGE_SIZE,
BOOTMEM_DEFAULT);
- if (mpf->mpf_physptr) {
+ if (mpf->physptr) {
unsigned long size = PAGE_SIZE;
#ifdef CONFIG_X86_32
/*
@@ -721,14 +722,14 @@ static int __init smp_scan_config(unsigned long base, unsigned long length,
* the bottom is mapped now.
* PC-9800's MPC table places on the very last
* of physical memory; so that simply reserving
- * PAGE_SIZE from mpg->mpf_physptr yields BUG()
+ * PAGE_SIZE from mpf->physptr yields BUG()
* in reserve_bootmem.
*/
unsigned long end = max_low_pfn * PAGE_SIZE;
- if (mpf->mpf_physptr + size > end)
- size = end - mpf->mpf_physptr;
+ if (mpf->physptr + size > end)
+ size = end - mpf->physptr;
#endif
- reserve_bootmem_generic(mpf->mpf_physptr, size,
+ reserve_bootmem_generic(mpf->physptr, size,
BOOTMEM_DEFAULT);
}
@@ -808,15 +809,15 @@ static int __init get_MP_intsrc_index(struct mpc_intsrc *m)
/* not legacy */
for (i = 0; i < mp_irq_entries; i++) {
- if (mp_irqs[i].mp_irqtype != mp_INT)
+ if (mp_irqs[i].irqtype != mp_INT)
continue;
- if (mp_irqs[i].mp_irqflag != 0x0f)
+ if (mp_irqs[i].irqflag != 0x0f)
continue;
- if (mp_irqs[i].mp_srcbus != m->srcbus)
+ if (mp_irqs[i].srcbus != m->srcbus)
continue;
- if (mp_irqs[i].mp_srcbusirq != m->srcbusirq)
+ if (mp_irqs[i].srcbusirq != m->srcbusirq)
continue;
if (irq_used[i]) {
/* already claimed */
@@ -921,10 +922,10 @@ static int __init replace_intsrc_all(struct mpc_table *mpc,
if (irq_used[i])
continue;
- if (mp_irqs[i].mp_irqtype != mp_INT)
+ if (mp_irqs[i].irqtype != mp_INT)
continue;
- if (mp_irqs[i].mp_irqflag != 0x0f)
+ if (mp_irqs[i].irqflag != 0x0f)
continue;
if (nr_m_spare > 0) {
@@ -1000,7 +1001,7 @@ static int __init update_mp_table(void)
{
char str[16];
char oem[10];
- struct intel_mp_floating *mpf;
+ struct mpf_intel *mpf;
struct mpc_table *mpc, *mpc_new;
if (!enable_update_mptable)
@@ -1013,19 +1014,19 @@ static int __init update_mp_table(void)
/*
* Now see if we need to go further.
*/
- if (mpf->mpf_feature1 != 0)
+ if (mpf->feature1 != 0)
return 0;
- if (!mpf->mpf_physptr)
+ if (!mpf->physptr)
return 0;
- mpc = phys_to_virt(mpf->mpf_physptr);
+ mpc = phys_to_virt(mpf->physptr);
if (!smp_check_mpc(mpc, oem, str))
return 0;
printk(KERN_INFO "mpf: %lx\n", virt_to_phys(mpf));
- printk(KERN_INFO "mpf_physptr: %x\n", mpf->mpf_physptr);
+ printk(KERN_INFO "physptr: %x\n", mpf->physptr);
if (mpc_new_phys && mpc->length > mpc_new_length) {
mpc_new_phys = 0;
@@ -1046,23 +1047,23 @@ static int __init update_mp_table(void)
}
printk(KERN_INFO "use in-positon replacing\n");
} else {
- mpf->mpf_physptr = mpc_new_phys;
+ mpf->physptr = mpc_new_phys;
mpc_new = phys_to_virt(mpc_new_phys);
memcpy(mpc_new, mpc, mpc->length);
mpc = mpc_new;
/* check if we can modify that */
- if (mpc_new_phys - mpf->mpf_physptr) {
- struct intel_mp_floating *mpf_new;
+ if (mpc_new_phys - mpf->physptr) {
+ struct mpf_intel *mpf_new;
/* steal 16 bytes from [0, 1k) */
printk(KERN_INFO "mpf new: %x\n", 0x400 - 16);
mpf_new = phys_to_virt(0x400 - 16);
memcpy(mpf_new, mpf, 16);
mpf = mpf_new;
- mpf->mpf_physptr = mpc_new_phys;
+ mpf->physptr = mpc_new_phys;
}
- mpf->mpf_checksum = 0;
- mpf->mpf_checksum -= mpf_checksum((unsigned char *)mpf, 16);
- printk(KERN_INFO "mpf_physptr new: %x\n", mpf->mpf_physptr);
+ mpf->checksum = 0;
+ mpf->checksum -= mpf_checksum((unsigned char *)mpf, 16);
+ printk(KERN_INFO "physptr new: %x\n", mpf->physptr);
}
/*
diff --git a/arch/x86/kernel/msr.c b/arch/x86/kernel/msr.c
index 7262666..3cf3413 100644
--- a/arch/x86/kernel/msr.c
+++ b/arch/x86/kernel/msr.c
@@ -35,10 +35,10 @@
#include <linux/device.h>
#include <linux/cpu.h>
#include <linux/notifier.h>
+#include <linux/uaccess.h>
#include <asm/processor.h>
#include <asm/msr.h>
-#include <asm/uaccess.h>
#include <asm/system.h>
static struct class *msr_class;
diff --git a/arch/x86/kernel/nmi.c b/arch/x86/kernel/nmi.c
index 7228979..23b6d9e 100644
--- a/arch/x86/kernel/nmi.c
+++ b/arch/x86/kernel/nmi.c
@@ -61,11 +61,7 @@ static int endflag __initdata;
static inline unsigned int get_nmi_count(int cpu)
{
-#ifdef CONFIG_X86_64
- return cpu_pda(cpu)->__nmi_count;
-#else
- return nmi_count(cpu);
-#endif
+ return per_cpu(irq_stat, cpu).__nmi_count;
}
static inline int mce_in_progress(void)
@@ -82,12 +78,8 @@ static inline int mce_in_progress(void)
*/
static inline unsigned int get_timer_irqs(int cpu)
{
-#ifdef CONFIG_X86_64
- return read_pda(apic_timer_irqs) + read_pda(irq0_irqs);
-#else
return per_cpu(irq_stat, cpu).apic_timer_irqs +
per_cpu(irq_stat, cpu).irq0_irqs;
-#endif
}
#ifdef CONFIG_SMP
diff --git a/arch/x86/kernel/process_32.c b/arch/x86/kernel/process_32.c
index a546f55..2c00a57 100644
--- a/arch/x86/kernel/process_32.c
+++ b/arch/x86/kernel/process_32.c
@@ -66,9 +66,6 @@ asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
EXPORT_PER_CPU_SYMBOL(current_task);
-DEFINE_PER_CPU(int, cpu_number);
-EXPORT_PER_CPU_SYMBOL(cpu_number);
-
/*
* Return saved PC of a blocked thread.
*/
@@ -591,7 +588,7 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
if (prev->gs | next->gs)
loadsegment(gs, next->gs);
- x86_write_percpu(current_task, next_p);
+ percpu_write(current_task, next_p);
return prev_p;
}
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 416fb92..4523ff8 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -57,6 +57,12 @@
asmlinkage extern void ret_from_fork(void);
+DEFINE_PER_CPU(struct task_struct *, current_task) = &init_task;
+EXPORT_PER_CPU_SYMBOL(current_task);
+
+DEFINE_PER_CPU(unsigned long, old_rsp);
+static DEFINE_PER_CPU(unsigned char, is_idle);
+
unsigned long kernel_thread_flags = CLONE_VM | CLONE_UNTRACED;
static ATOMIC_NOTIFIER_HEAD(idle_notifier);
@@ -75,13 +81,13 @@ EXPORT_SYMBOL_GPL(idle_notifier_unregister);
void enter_idle(void)
{
- write_pda(isidle, 1);
+ percpu_write(is_idle, 1);
atomic_notifier_call_chain(&idle_notifier, IDLE_START, NULL);
}
static void __exit_idle(void)
{
- if (test_and_clear_bit_pda(0, isidle) == 0)
+ if (x86_test_and_clear_bit_percpu(0, is_idle) == 0)
return;
atomic_notifier_call_chain(&idle_notifier, IDLE_END, NULL);
}
@@ -392,7 +398,7 @@ start_thread(struct pt_regs *regs, unsigned long new_ip, unsigned long new_sp)
load_gs_index(0);
regs->ip = new_ip;
regs->sp = new_sp;
- write_pda(oldrsp, new_sp);
+ percpu_write(old_rsp, new_sp);
regs->cs = __USER_CS;
regs->ss = __USER_DS;
regs->flags = 0x200;
@@ -613,13 +619,13 @@ __switch_to(struct task_struct *prev_p, struct task_struct *next_p)
/*
* Switch the PDA and FPU contexts.
*/
- prev->usersp = read_pda(oldrsp);
- write_pda(oldrsp, next->usersp);
- write_pda(pcurrent, next_p);
+ prev->usersp = percpu_read(old_rsp);
+ percpu_write(old_rsp, next->usersp);
+ percpu_write(current_task, next_p);
- write_pda(kernelstack,
+ percpu_write(kernel_stack,
(unsigned long)task_stack_page(next_p) +
- THREAD_SIZE - PDA_STACKOFFSET);
+ THREAD_SIZE - KERNEL_STACK_OFFSET);
#ifdef CONFIG_CC_STACKPROTECTOR
write_pda(stack_canary, next_p->stack_canary);
/*
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 2b46eb4..f8536fe 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -14,6 +14,7 @@
#include <asm/reboot.h>
#include <asm/pci_x86.h>
#include <asm/virtext.h>
+#include <asm/cpu.h>
#ifdef CONFIG_X86_32
# include <linux/dmi.h>
diff --git a/arch/x86/kernel/setup.c b/arch/x86/kernel/setup.c
index ae0d804..f41c448 100644
--- a/arch/x86/kernel/setup.c
+++ b/arch/x86/kernel/setup.c
@@ -89,7 +89,7 @@
#include <asm/system.h>
#include <asm/vsyscall.h>
-#include <asm/smp.h>
+#include <asm/cpu.h>
#include <asm/desc.h>
#include <asm/dma.h>
#include <asm/iommu.h>
diff --git a/arch/x86/kernel/setup_percpu.c b/arch/x86/kernel/setup_percpu.c
index 55c4607..efbafbb 100644
--- a/arch/x86/kernel/setup_percpu.c
+++ b/arch/x86/kernel/setup_percpu.c
@@ -13,6 +13,23 @@
#include <asm/mpspec.h>
#include <asm/apicdef.h>
#include <asm/highmem.h>
+#include <asm/proto.h>
+#include <asm/cpumask.h>
+
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+# define DBG(x...) printk(KERN_DEBUG x)
+#else
+# define DBG(x...)
+#endif
+
+/*
+ * Could be inside CONFIG_HAVE_SETUP_PER_CPU_AREA with other stuff but
+ * voyager wants cpu_number too.
+ */
+#ifdef CONFIG_SMP
+DEFINE_PER_CPU(int, cpu_number);
+EXPORT_PER_CPU_SYMBOL(cpu_number);
+#endif
#ifdef CONFIG_X86_LOCAL_APIC
unsigned int num_processors;
@@ -26,31 +43,84 @@ unsigned int max_physical_apicid;
physid_mask_t phys_cpu_present_map;
#endif
-/* map cpu index to physical APIC ID */
+/*
+ * Map cpu index to physical APIC ID
+ */
DEFINE_EARLY_PER_CPU(u16, x86_cpu_to_apicid, BAD_APICID);
DEFINE_EARLY_PER_CPU(u16, x86_bios_cpu_apicid, BAD_APICID);
EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_apicid);
EXPORT_EARLY_PER_CPU_SYMBOL(x86_bios_cpu_apicid);
#if defined(CONFIG_NUMA) && defined(CONFIG_X86_64)
-#define X86_64_NUMA 1
+#define X86_64_NUMA 1 /* (used later) */
+DEFINE_PER_CPU(int, node_number) = 0;
+EXPORT_PER_CPU_SYMBOL(node_number);
-/* map cpu index to node index */
+/*
+ * Map cpu index to node index
+ */
DEFINE_EARLY_PER_CPU(int, x86_cpu_to_node_map, NUMA_NO_NODE);
EXPORT_EARLY_PER_CPU_SYMBOL(x86_cpu_to_node_map);
-/* which logical CPUs are on which nodes */
+/*
+ * Which logical CPUs are on which nodes
+ */
cpumask_t *node_to_cpumask_map;
EXPORT_SYMBOL(node_to_cpumask_map);
-/* setup node_to_cpumask_map */
+/*
+ * Setup node_to_cpumask_map
+ */
static void __init setup_node_to_cpumask_map(void);
#else
static inline void setup_node_to_cpumask_map(void) { }
#endif
-#if defined(CONFIG_HAVE_SETUP_PER_CPU_AREA) && defined(CONFIG_X86_SMP)
+/*
+ * Define load_pda_offset() and per-cpu __pda for x86_64.
+ * load_pda_offset() is responsible for loading the offset of pda into
+ * %gs.
+ *
+ * On SMP, pda offset also duals as percpu base address and thus it
+ * should be at the start of per-cpu area. To achieve this, it's
+ * preallocated in vmlinux_64.lds.S directly instead of using
+ * DEFINE_PER_CPU().
+ */
+#ifdef CONFIG_X86_64
+void __cpuinit load_pda_offset(int cpu)
+{
+ /* Memory clobbers used to order pda/percpu accesses */
+ mb();
+ wrmsrl(MSR_GS_BASE, cpu_pda(cpu));
+ mb();
+}
+#ifndef CONFIG_SMP
+DEFINE_PER_CPU(struct x8664_pda, __pda);
+#endif
+EXPORT_PER_CPU_SYMBOL(__pda);
+#endif /* CONFIG_SMP && CONFIG_X86_64 */
+
+#ifdef CONFIG_X86_64
+
+/* correctly size the local cpu masks */
+static void setup_cpu_local_masks(void)
+{
+ alloc_bootmem_cpumask_var(&cpu_initialized_mask);
+ alloc_bootmem_cpumask_var(&cpu_callin_mask);
+ alloc_bootmem_cpumask_var(&cpu_callout_mask);
+ alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask);
+}
+
+#else /* CONFIG_X86_32 */
+
+static inline void setup_cpu_local_masks(void)
+{
+}
+
+#endif /* CONFIG_X86_32 */
+
+#ifdef CONFIG_HAVE_SETUP_PER_CPU_AREA
/*
* Copy data used in early init routines from the initial arrays to the
* per cpu data areas. These arrays then become expendable and the
@@ -79,78 +149,14 @@ static void __init setup_per_cpu_maps(void)
#endif
}
-#ifdef CONFIG_X86_32
-/*
- * Great future not-so-futuristic plan: make i386 and x86_64 do it
- * the same way
- */
+#ifdef CONFIG_X86_64
+unsigned long __per_cpu_offset[NR_CPUS] __read_mostly = {
+ [0] = (unsigned long)__per_cpu_load,
+};
+#else
unsigned long __per_cpu_offset[NR_CPUS] __read_mostly;
+#endif
EXPORT_SYMBOL(__per_cpu_offset);
-static inline void setup_cpu_pda_map(void) { }
-
-#elif !defined(CONFIG_SMP)
-static inline void setup_cpu_pda_map(void) { }
-
-#else /* CONFIG_SMP && CONFIG_X86_64 */
-
-/*
- * Allocate cpu_pda pointer table and array via alloc_bootmem.
- */
-static void __init setup_cpu_pda_map(void)
-{
- char *pda;
- struct x8664_pda **new_cpu_pda;
- unsigned long size;
- int cpu;
-
- size = roundup(sizeof(struct x8664_pda), cache_line_size());
-
- /* allocate cpu_pda array and pointer table */
- {
- unsigned long tsize = nr_cpu_ids * sizeof(void *);
- unsigned long asize = size * (nr_cpu_ids - 1);
-
- tsize = roundup(tsize, cache_line_size());
- new_cpu_pda = alloc_bootmem(tsize + asize);
- pda = (char *)new_cpu_pda + tsize;
- }
-
- /* initialize pointer table to static pda's */
- for_each_possible_cpu(cpu) {
- if (cpu == 0) {
- /* leave boot cpu pda in place */
- new_cpu_pda[0] = cpu_pda(0);
- continue;
- }
- new_cpu_pda[cpu] = (struct x8664_pda *)pda;
- new_cpu_pda[cpu]->in_bootmem = 1;
- pda += size;
- }
-
- /* point to new pointer table */
- _cpu_pda = new_cpu_pda;
-}
-
-#endif /* CONFIG_SMP && CONFIG_X86_64 */
-
-#ifdef CONFIG_X86_64
-
-/* correctly size the local cpu masks */
-static void setup_cpu_local_masks(void)
-{
- alloc_bootmem_cpumask_var(&cpu_initialized_mask);
- alloc_bootmem_cpumask_var(&cpu_callin_mask);
- alloc_bootmem_cpumask_var(&cpu_callout_mask);
- alloc_bootmem_cpumask_var(&cpu_sibling_setup_mask);
-}
-
-#else /* CONFIG_X86_32 */
-
-static inline void setup_cpu_local_masks(void)
-{
-}
-
-#endif /* CONFIG_X86_32 */
/*
* Great future plan:
@@ -164,9 +170,6 @@ void __init setup_per_cpu_areas(void)
int cpu;
unsigned long align = 1;
- /* Setup cpu_pda map */
- setup_cpu_pda_map();
-
/* Copy section for each CPU (we discard the original) */
old_size = PERCPU_ENOUGH_ROOM;
align = max_t(unsigned long, PAGE_SIZE, align);
@@ -197,8 +200,25 @@ void __init setup_per_cpu_areas(void)
cpu, node, __pa(ptr));
}
#endif
+
+ memcpy(ptr, __per_cpu_load, __per_cpu_end - __per_cpu_start);
per_cpu_offset(cpu) = ptr - __per_cpu_start;
- memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
+ per_cpu(this_cpu_off, cpu) = per_cpu_offset(cpu);
+ per_cpu(cpu_number, cpu) = cpu;
+#ifdef CONFIG_X86_64
+ per_cpu(irq_stack_ptr, cpu) =
+ (char *)per_cpu(irq_stack, cpu) + IRQ_STACK_SIZE - 64;
+ /*
+ * CPU0 modified pda in the init data area, reload pda
+ * offset for CPU0 and clear the area for others.
+ */
+ if (cpu == 0)
+ load_pda_offset(0);
+ else
+ memset(cpu_pda(cpu), 0, sizeof(*cpu_pda(cpu)));
+#endif
+
+ DBG("PERCPU: cpu %4d %p\n", cpu, ptr);
}
/* Setup percpu data maps */
@@ -220,6 +240,7 @@ void __init setup_per_cpu_areas(void)
* Requires node_possible_map to be valid.
*
* Note: node_to_cpumask() is not valid until after this is done.
+ * (Use CONFIG_DEBUG_PER_CPU_MAPS to check this.)
*/
static void __init setup_node_to_cpumask_map(void)
{
@@ -235,6 +256,7 @@ static void __init setup_node_to_cpumask_map(void)
/* allocate the map */
map = alloc_bootmem_low(nr_node_ids * sizeof(cpumask_t));
+ DBG("node_to_cpumask_map at %p for %d nodes\n", map, nr_node_ids);
pr_debug("Node to cpumask map at %p for %d nodes\n",
map, nr_node_ids);
@@ -247,17 +269,23 @@ void __cpuinit numa_set_node(int cpu, int node)
{
int *cpu_to_node_map = early_per_cpu_ptr(x86_cpu_to_node_map);
- if (cpu_pda(cpu) && node != NUMA_NO_NODE)
- cpu_pda(cpu)->nodenumber = node;
-
- if (cpu_to_node_map)
+ /* early setting, no percpu area yet */
+ if (cpu_to_node_map) {
cpu_to_node_map[cpu] = node;
+ return;
+ }
- else if (per_cpu_offset(cpu))
- per_cpu(x86_cpu_to_node_map, cpu) = node;
+#ifdef CONFIG_DEBUG_PER_CPU_MAPS
+ if (cpu >= nr_cpu_ids || !per_cpu_offset(cpu)) {
+ printk(KERN_ERR "numa_set_node: invalid cpu# (%d)\n", cpu);
+ dump_stack();
+ return;
+ }
+#endif
+ per_cpu(x86_cpu_to_node_map, cpu) = node;
- else
- pr_debug("Setting node for non-present cpu %d\n", cpu);
+ if (node != NUMA_NO_NODE)
+ per_cpu(node_number, cpu) = node;
}
void __cpuinit numa_clear_node(int cpu)
@@ -274,7 +302,7 @@ void __cpuinit numa_add_cpu(int cpu)
void __cpuinit numa_remove_cpu(int cpu)
{
- cpu_clear(cpu, node_to_cpumask_map[cpu_to_node(cpu)]);
+ cpu_clear(cpu, node_to_cpumask_map[early_cpu_to_node(cpu)]);
}
#else /* CONFIG_DEBUG_PER_CPU_MAPS */
@@ -284,7 +312,7 @@ void __cpuinit numa_remove_cpu(int cpu)
*/
static void __cpuinit numa_set_cpumask(int cpu, int enable)
{
- int node = cpu_to_node(cpu);
+ int node = early_cpu_to_node(cpu);
cpumask_t *mask;
char buf[64];
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
index bb1a3b1..869b988 100644
--- a/arch/x86/kernel/smpboot.c
+++ b/arch/x86/kernel/smpboot.c
@@ -53,7 +53,6 @@
#include <asm/nmi.h>
#include <asm/irq.h>
#include <asm/idle.h>
-#include <asm/smp.h>
#include <asm/trampoline.h>
#include <asm/cpu.h>
#include <asm/numa.h>
@@ -745,52 +744,6 @@ static void __cpuinit do_fork_idle(struct work_struct *work)
complete(&c_idle->done);
}
-#ifdef CONFIG_X86_64
-
-/* __ref because it's safe to call free_bootmem when after_bootmem == 0. */
-static void __ref free_bootmem_pda(struct x8664_pda *oldpda)
-{
- if (!after_bootmem)
- free_bootmem((unsigned long)oldpda, sizeof(*oldpda));
-}
-
-/*
- * Allocate node local memory for the AP pda.
- *
- * Must be called after the _cpu_pda pointer table is initialized.
- */
-int __cpuinit get_local_pda(int cpu)
-{
- struct x8664_pda *oldpda, *newpda;
- unsigned long size = sizeof(struct x8664_pda);
- int node = cpu_to_node(cpu);
-
- if (cpu_pda(cpu) && !cpu_pda(cpu)->in_bootmem)
- return 0;
-
- oldpda = cpu_pda(cpu);
- newpda = kmalloc_node(size, GFP_ATOMIC, node);
- if (!newpda) {
- printk(KERN_ERR "Could not allocate node local PDA "
- "for CPU %d on node %d\n", cpu, node);
-
- if (oldpda)
- return 0; /* have a usable pda */
- else
- return -1;
- }
-
- if (oldpda) {
- memcpy(newpda, oldpda, size);
- free_bootmem_pda(oldpda);
- }
-
- newpda->in_bootmem = 0;
- cpu_pda(cpu) = newpda;
- return 0;
-}
-#endif /* CONFIG_X86_64 */
-
static int __cpuinit do_boot_cpu(int apicid, int cpu)
/*
* NOTE - on most systems this is a PHYSICAL apic ID, but on multiquad
@@ -808,16 +761,6 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
};
INIT_WORK(&c_idle.work, do_fork_idle);
-#ifdef CONFIG_X86_64
- /* Allocate node local memory for AP pdas */
- if (cpu > 0) {
- boot_error = get_local_pda(cpu);
- if (boot_error)
- goto restore_state;
- /* if can't get pda memory, can't start cpu */
- }
-#endif
-
alternatives_smp_switch(1);
c_idle.idle = get_idle_for_cpu(cpu);
@@ -847,14 +790,17 @@ static int __cpuinit do_boot_cpu(int apicid, int cpu)
set_idle_for_cpu(cpu, c_idle.idle);
do_rest:
-#ifdef CONFIG_X86_32
per_cpu(current_task, cpu) = c_idle.idle;
+#ifdef CONFIG_X86_32
init_gdt(cpu);
/* Stack for startup_32 can be just as for start_secondary onwards */
irq_ctx_init(cpu);
#else
- cpu_pda(cpu)->pcurrent = c_idle.idle;
clear_tsk_thread_flag(c_idle.idle, TIF_FORK);
+ initial_gs = per_cpu_offset(cpu);
+ per_cpu(kernel_stack, cpu) =
+ (unsigned long)task_stack_page(c_idle.idle) -
+ KERNEL_STACK_OFFSET + THREAD_SIZE;
#endif
early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
initial_code = (unsigned long)start_secondary;
@@ -931,9 +877,7 @@ do_rest:
inquire_remote_apic(apicid);
}
}
-#ifdef CONFIG_X86_64
-restore_state:
-#endif
+
if (boot_error) {
/* Try to put things back the way they were before ... */
numa_remove_cpu(cpu); /* was set by numa_add_cpu */
@@ -1125,6 +1069,7 @@ static int __init smp_sanity_check(unsigned max_cpus)
printk(KERN_ERR "... forcing use of dummy APIC emulation."
"(tell your hw vendor)\n");
smpboot_clear_io_apic();
+ disable_ioapic_setup();
return -1;
}
diff --git a/arch/x86/kernel/smpcommon.c b/arch/x86/kernel/smpcommon.c
index 397e309..add36b4 100644
--- a/arch/x86/kernel/smpcommon.c
+++ b/arch/x86/kernel/smpcommon.c
@@ -3,11 +3,16 @@
*/
#include <linux/module.h>
#include <asm/smp.h>
+#include <asm/sections.h>
-#ifdef CONFIG_X86_32
+#ifdef CONFIG_X86_64
+DEFINE_PER_CPU(unsigned long, this_cpu_off) = (unsigned long)__per_cpu_load;
+#else
DEFINE_PER_CPU(unsigned long, this_cpu_off);
+#endif
EXPORT_PER_CPU_SYMBOL(this_cpu_off);
+#ifdef CONFIG_X86_32
/*
* Initialize the CPU's GDT. This is either the boot CPU doing itself
* (still using the master per-cpu area), or a CPU doing it for a
@@ -23,8 +28,5 @@ __cpuinit void init_gdt(int cpu)
write_gdt_entry(get_cpu_gdt_table(cpu),
GDT_ENTRY_PERCPU, &gdt, DESCTYPE_S);
-
- per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
- per_cpu(cpu_number, cpu) = cpu;
}
#endif
diff --git a/arch/x86/kernel/tlb_32.c b/arch/x86/kernel/tlb_32.c
index ce50546..abf0808 100644
--- a/arch/x86/kernel/tlb_32.c
+++ b/arch/x86/kernel/tlb_32.c
@@ -4,8 +4,8 @@
#include <asm/tlbflush.h>
-DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate)
- ____cacheline_aligned = { &init_mm, 0, };
+DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate)
+ = { &init_mm, 0, };
/* must come after the send_IPI functions above for inlining */
#include <mach_ipi.h>
@@ -20,7 +20,7 @@ DEFINE_PER_CPU(struct tlb_state, cpu_tlbstate)
* Optimizations Manfred Spraul <manfred@colorfullife.com>
*/
-static cpumask_t flush_cpumask;
+static cpumask_var_t flush_cpumask;
static struct mm_struct *flush_mm;
static unsigned long flush_va;
static DEFINE_SPINLOCK(tlbstate_lock);
@@ -34,8 +34,8 @@ static DEFINE_SPINLOCK(tlbstate_lock);
*/
void leave_mm(int cpu)
{
- BUG_ON(x86_read_percpu(cpu_tlbstate.state) == TLBSTATE_OK);
- cpu_clear(cpu, x86_read_percpu(cpu_tlbstate.active_mm)->cpu_vm_mask);
+ BUG_ON(percpu_read(cpu_tlbstate.state) == TLBSTATE_OK);
+ cpu_clear(cpu, percpu_read(cpu_tlbstate.active_mm)->cpu_vm_mask);
load_cr3(swapper_pg_dir);
}
EXPORT_SYMBOL_GPL(leave_mm);
@@ -92,7 +92,7 @@ void smp_invalidate_interrupt(struct pt_regs *regs)
cpu = get_cpu();
- if (!cpu_isset(cpu, flush_cpumask))
+ if (!cpumask_test_cpu(cpu, flush_cpumask))
goto out;
/*
* This was a BUG() but until someone can quote me the
@@ -103,8 +103,8 @@ void smp_invalidate_interrupt(struct pt_regs *regs)
* BUG();
*/
- if (flush_mm == x86_read_percpu(cpu_tlbstate.active_mm)) {
- if (x86_read_percpu(cpu_tlbstate.state) == TLBSTATE_OK) {
+ if (flush_mm == percpu_read(cpu_tlbstate.active_mm)) {
+ if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) {
if (flush_va == TLB_FLUSH_ALL)
local_flush_tlb();
else
@@ -114,35 +114,22 @@ void smp_invalidate_interrupt(struct pt_regs *regs)
}
ack_APIC_irq();
smp_mb__before_clear_bit();
- cpu_clear(cpu, flush_cpumask);
+ cpumask_clear_cpu(cpu, flush_cpumask);
smp_mb__after_clear_bit();
out:
put_cpu_no_resched();
inc_irq_stat(irq_tlb_count);
}
-void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
- unsigned long va)
+void native_flush_tlb_others(const struct cpumask *cpumask,
+ struct mm_struct *mm, unsigned long va)
{
- cpumask_t cpumask = *cpumaskp;
-
/*
- * A couple of (to be removed) sanity checks:
- *
- * - current CPU must not be in mask
* - mask must exist :)
*/
- BUG_ON(cpus_empty(cpumask));
- BUG_ON(cpu_isset(smp_processor_id(), cpumask));
+ BUG_ON(cpumask_empty(cpumask));
BUG_ON(!mm);
-#ifdef CONFIG_HOTPLUG_CPU
- /* If a CPU which we ran on has gone down, OK. */
- cpus_and(cpumask, cpumask, cpu_online_map);
- if (unlikely(cpus_empty(cpumask)))
- return;
-#endif
-
/*
* i'm not happy about this global shared spinlock in the
* MM hot path, but we'll see how contended it is.
@@ -150,9 +137,17 @@ void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
*/
spin_lock(&tlbstate_lock);
+ cpumask_andnot(flush_cpumask, cpumask, cpumask_of(smp_processor_id()));
+#ifdef CONFIG_HOTPLUG_CPU
+ /* If a CPU which we ran on has gone down, OK. */
+ cpumask_and(flush_cpumask, flush_cpumask, cpu_online_mask);
+ if (unlikely(cpumask_empty(flush_cpumask))) {
+ spin_unlock(&tlbstate_lock);
+ return;
+ }
+#endif
flush_mm = mm;
flush_va = va;
- cpus_or(flush_cpumask, cpumask, flush_cpumask);
/*
* Make the above memory operations globally visible before
@@ -163,9 +158,9 @@ void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
* We have to send the IPI only to
* CPUs affected.
*/
- send_IPI_mask(&cpumask, INVALIDATE_TLB_VECTOR);
+ send_IPI_mask(flush_cpumask, INVALIDATE_TLB_VECTOR);
- while (!cpus_empty(flush_cpumask))
+ while (!cpumask_empty(flush_cpumask))
/* nothing. lockup detection does not belong here */
cpu_relax();
@@ -177,25 +172,19 @@ void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
void flush_tlb_current_task(void)
{
struct mm_struct *mm = current->mm;
- cpumask_t cpu_mask;
preempt_disable();
- cpu_mask = mm->cpu_vm_mask;
- cpu_clear(smp_processor_id(), cpu_mask);
local_flush_tlb();
- if (!cpus_empty(cpu_mask))
- flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
+ if (cpumask_any_but(&mm->cpu_vm_mask, smp_processor_id()) < nr_cpu_ids)
+ flush_tlb_others(&mm->cpu_vm_mask, mm, TLB_FLUSH_ALL);
preempt_enable();
}
void flush_tlb_mm(struct mm_struct *mm)
{
- cpumask_t cpu_mask;
preempt_disable();
- cpu_mask = mm->cpu_vm_mask;
- cpu_clear(smp_processor_id(), cpu_mask);
if (current->active_mm == mm) {
if (current->mm)
@@ -203,8 +192,8 @@ void flush_tlb_mm(struct mm_struct *mm)
else
leave_mm(smp_processor_id());
}
- if (!cpus_empty(cpu_mask))
- flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
+ if (cpumask_any_but(&mm->cpu_vm_mask, smp_processor_id()) < nr_cpu_ids)
+ flush_tlb_others(&mm->cpu_vm_mask, mm, TLB_FLUSH_ALL);
preempt_enable();
}
@@ -212,11 +201,8 @@ void flush_tlb_mm(struct mm_struct *mm)
void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
{
struct mm_struct *mm = vma->vm_mm;
- cpumask_t cpu_mask;
preempt_disable();
- cpu_mask = mm->cpu_vm_mask;
- cpu_clear(smp_processor_id(), cpu_mask);
if (current->active_mm == mm) {
if (current->mm)
@@ -225,9 +211,8 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
leave_mm(smp_processor_id());
}
- if (!cpus_empty(cpu_mask))
- flush_tlb_others(cpu_mask, mm, va);
-
+ if (cpumask_any_but(&mm->cpu_vm_mask, smp_processor_id()) < nr_cpu_ids)
+ flush_tlb_others(&mm->cpu_vm_mask, mm, va);
preempt_enable();
}
EXPORT_SYMBOL(flush_tlb_page);
@@ -237,7 +222,7 @@ static void do_flush_tlb_all(void *info)
unsigned long cpu = smp_processor_id();
__flush_tlb_all();
- if (x86_read_percpu(cpu_tlbstate.state) == TLBSTATE_LAZY)
+ if (percpu_read(cpu_tlbstate.state) == TLBSTATE_LAZY)
leave_mm(cpu);
}
@@ -246,11 +231,9 @@ void flush_tlb_all(void)
on_each_cpu(do_flush_tlb_all, NULL, 1);
}
-void reset_lazy_tlbstate(void)
+static int init_flush_cpumask(void)
{
- int cpu = raw_smp_processor_id();
-
- per_cpu(cpu_tlbstate, cpu).state = 0;
- per_cpu(cpu_tlbstate, cpu).active_mm = &init_mm;
+ alloc_cpumask_var(&flush_cpumask, GFP_KERNEL);
+ return 0;
}
-
+early_initcall(init_flush_cpumask);
diff --git a/arch/x86/kernel/tlb_64.c b/arch/x86/kernel/tlb_64.c
index f8be6f1..e64a32c 100644
--- a/arch/x86/kernel/tlb_64.c
+++ b/arch/x86/kernel/tlb_64.c
@@ -18,6 +18,9 @@
#include <asm/uv/uv_hub.h>
#include <asm/uv/uv_bau.h>
+DEFINE_PER_CPU_SHARED_ALIGNED(struct tlb_state, cpu_tlbstate)
+ = { &init_mm, 0, };
+
#include <mach_ipi.h>
/*
* Smarter SMP flushing macros.
@@ -43,10 +46,10 @@
union smp_flush_state {
struct {
- cpumask_t flush_cpumask;
struct mm_struct *flush_mm;
unsigned long flush_va;
spinlock_t tlbstate_lock;
+ DECLARE_BITMAP(flush_cpumask, NR_CPUS);
};
char pad[SMP_CACHE_BYTES];
} ____cacheline_aligned;
@@ -62,9 +65,9 @@ static DEFINE_PER_CPU(union smp_flush_state, flush_state);
*/
void leave_mm(int cpu)
{
- if (read_pda(mmu_state) == TLBSTATE_OK)
+ if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK)
BUG();
- cpu_clear(cpu, read_pda(active_mm)->cpu_vm_mask);
+ cpu_clear(cpu, percpu_read(cpu_tlbstate.active_mm)->cpu_vm_mask);
load_cr3(swapper_pg_dir);
}
EXPORT_SYMBOL_GPL(leave_mm);
@@ -131,7 +134,7 @@ asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs)
sender = ~regs->orig_ax - INVALIDATE_TLB_VECTOR_START;
f = &per_cpu(flush_state, sender);
- if (!cpu_isset(cpu, f->flush_cpumask))
+ if (!cpumask_test_cpu(cpu, to_cpumask(f->flush_cpumask)))
goto out;
/*
* This was a BUG() but until someone can quote me the
@@ -142,8 +145,8 @@ asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs)
* BUG();
*/
- if (f->flush_mm == read_pda(active_mm)) {
- if (read_pda(mmu_state) == TLBSTATE_OK) {
+ if (f->flush_mm == percpu_read(cpu_tlbstate.active_mm)) {
+ if (percpu_read(cpu_tlbstate.state) == TLBSTATE_OK) {
if (f->flush_va == TLB_FLUSH_ALL)
local_flush_tlb();
else
@@ -153,19 +156,15 @@ asmlinkage void smp_invalidate_interrupt(struct pt_regs *regs)
}
out:
ack_APIC_irq();
- cpu_clear(cpu, f->flush_cpumask);
+ cpumask_clear_cpu(cpu, to_cpumask(f->flush_cpumask));
inc_irq_stat(irq_tlb_count);
}
-void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
- unsigned long va)
+static void flush_tlb_others_ipi(const struct cpumask *cpumask,
+ struct mm_struct *mm, unsigned long va)
{
int sender;
union smp_flush_state *f;
- cpumask_t cpumask = *cpumaskp;
-
- if (is_uv_system() && uv_flush_tlb_others(&cpumask, mm, va))
- return;
/* Caller has disabled preemption */
sender = smp_processor_id() % NUM_INVALIDATE_TLB_VECTORS;
@@ -180,7 +179,8 @@ void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
f->flush_mm = mm;
f->flush_va = va;
- cpus_or(f->flush_cpumask, cpumask, f->flush_cpumask);
+ cpumask_andnot(to_cpumask(f->flush_cpumask),
+ cpumask, cpumask_of(smp_processor_id()));
/*
* Make the above memory operations globally visible before
@@ -191,9 +191,10 @@ void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
* We have to send the IPI only to
* CPUs affected.
*/
- send_IPI_mask(&cpumask, INVALIDATE_TLB_VECTOR_START + sender);
+ send_IPI_mask(to_cpumask(f->flush_cpumask),
+ INVALIDATE_TLB_VECTOR_START + sender);
- while (!cpus_empty(f->flush_cpumask))
+ while (!cpumask_empty(to_cpumask(f->flush_cpumask)))
cpu_relax();
f->flush_mm = NULL;
@@ -201,6 +202,25 @@ void native_flush_tlb_others(const cpumask_t *cpumaskp, struct mm_struct *mm,
spin_unlock(&f->tlbstate_lock);
}
+void native_flush_tlb_others(const struct cpumask *cpumask,
+ struct mm_struct *mm, unsigned long va)
+{
+ if (is_uv_system()) {
+ /* FIXME: could be an percpu_alloc'd thing */
+ static DEFINE_PER_CPU(cpumask_t, flush_tlb_mask);
+ struct cpumask *after_uv_flush = &get_cpu_var(flush_tlb_mask);
+
+ cpumask_andnot(after_uv_flush, cpumask,
+ cpumask_of(smp_processor_id()));
+ if (!uv_flush_tlb_others(after_uv_flush, mm, va))
+ flush_tlb_others_ipi(after_uv_flush, mm, va);
+
+ put_cpu_var(flush_tlb_uv_cpumask);
+ return;
+ }
+ flush_tlb_others_ipi(cpumask, mm, va);
+}
+
static int __cpuinit init_smp_flush(void)
{
int i;
@@ -215,25 +235,18 @@ core_initcall(init_smp_flush);
void flush_tlb_current_task(void)
{
struct mm_struct *mm = current->mm;
- cpumask_t cpu_mask;
preempt_disable();
- cpu_mask = mm->cpu_vm_mask;
- cpu_clear(smp_processor_id(), cpu_mask);
local_flush_tlb();
- if (!cpus_empty(cpu_mask))
- flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
+ if (cpumask_any_but(&mm->cpu_vm_mask, smp_processor_id()) < nr_cpu_ids)
+ flush_tlb_others(&mm->cpu_vm_mask, mm, TLB_FLUSH_ALL);
preempt_enable();
}
void flush_tlb_mm(struct mm_struct *mm)
{
- cpumask_t cpu_mask;
-
preempt_disable();
- cpu_mask = mm->cpu_vm_mask;
- cpu_clear(smp_processor_id(), cpu_mask);
if (current->active_mm == mm) {
if (current->mm)
@@ -241,8 +254,8 @@ void flush_tlb_mm(struct mm_struct *mm)
else
leave_mm(smp_processor_id());
}
- if (!cpus_empty(cpu_mask))
- flush_tlb_others(cpu_mask, mm, TLB_FLUSH_ALL);
+ if (cpumask_any_but(&mm->cpu_vm_mask, smp_processor_id()) < nr_cpu_ids)
+ flush_tlb_others(&mm->cpu_vm_mask, mm, TLB_FLUSH_ALL);
preempt_enable();
}
@@ -250,11 +263,8 @@ void flush_tlb_mm(struct mm_struct *mm)
void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
{
struct mm_struct *mm = vma->vm_mm;
- cpumask_t cpu_mask;
preempt_disable();
- cpu_mask = mm->cpu_vm_mask;
- cpu_clear(smp_processor_id(), cpu_mask);
if (current->active_mm == mm) {
if (current->mm)
@@ -263,8 +273,8 @@ void flush_tlb_page(struct vm_area_struct *vma, unsigned long va)
leave_mm(smp_processor_id());
}
- if (!cpus_empty(cpu_mask))
- flush_tlb_others(cpu_mask, mm, va);
+ if (cpumask_any_but(&mm->cpu_vm_mask, smp_processor_id()) < nr_cpu_ids)
+ flush_tlb_others(&mm->cpu_vm_mask, mm, va);
preempt_enable();
}
@@ -274,7 +284,7 @@ static void do_flush_tlb_all(void *info)
unsigned long cpu = smp_processor_id();
__flush_tlb_all();
- if (read_pda(mmu_state) == TLBSTATE_LAZY)
+ if (percpu_read(cpu_tlbstate.state) == TLBSTATE_LAZY)
leave_mm(cpu);
}
diff --git a/arch/x86/kernel/tlb_uv.c b/arch/x86/kernel/tlb_uv.c
index f885023..690dcf1 100644
--- a/arch/x86/kernel/tlb_uv.c
+++ b/arch/x86/kernel/tlb_uv.c
@@ -212,11 +212,11 @@ static int uv_wait_completion(struct bau_desc *bau_desc,
* The cpumaskp mask contains the cpus the broadcast was sent to.
*
* Returns 1 if all remote flushing was done. The mask is zeroed.
- * Returns 0 if some remote flushing remains to be done. The mask is left
- * unchanged.
+ * Returns 0 if some remote flushing remains to be done. The mask will have
+ * some bits still set.
*/
int uv_flush_send_and_wait(int cpu, int this_blade, struct bau_desc *bau_desc,
- cpumask_t *cpumaskp)
+ struct cpumask *cpumaskp)
{
int completion_status = 0;
int right_shift;
@@ -263,13 +263,13 @@ int uv_flush_send_and_wait(int cpu, int this_blade, struct bau_desc *bau_desc,
* Success, so clear the remote cpu's from the mask so we don't
* use the IPI method of shootdown on them.
*/
- for_each_cpu_mask(bit, *cpumaskp) {
+ for_each_cpu(bit, cpumaskp) {
blade = uv_cpu_to_blade_id(bit);
if (blade == this_blade)
continue;
- cpu_clear(bit, *cpumaskp);
+ cpumask_clear_cpu(bit, cpumaskp);
}
- if (!cpus_empty(*cpumaskp))
+ if (!cpumask_empty(cpumaskp))
return 0;
return 1;
}
@@ -296,7 +296,7 @@ int uv_flush_send_and_wait(int cpu, int this_blade, struct bau_desc *bau_desc,
* Returns 1 if all remote flushing was done.
* Returns 0 if some remote flushing remains to be done.
*/
-int uv_flush_tlb_others(cpumask_t *cpumaskp, struct mm_struct *mm,
+int uv_flush_tlb_others(struct cpumask *cpumaskp, struct mm_struct *mm,
unsigned long va)
{
int i;
@@ -315,7 +315,7 @@ int uv_flush_tlb_others(cpumask_t *cpumaskp, struct mm_struct *mm,
bau_nodes_clear(&bau_desc->distribution, UV_DISTRIBUTION_SIZE);
i = 0;
- for_each_cpu_mask(bit, *cpumaskp) {
+ for_each_cpu(bit, cpumaskp) {
blade = uv_cpu_to_blade_id(bit);
BUG_ON(blade > (UV_DISTRIBUTION_SIZE - 1));
if (blade == this_blade) {
diff --git a/arch/x86/kernel/vmlinux_32.lds.S b/arch/x86/kernel/vmlinux_32.lds.S
index 82c6755..3eba7f7 100644
--- a/arch/x86/kernel/vmlinux_32.lds.S
+++ b/arch/x86/kernel/vmlinux_32.lds.S
@@ -178,14 +178,7 @@ SECTIONS
__initramfs_end = .;
}
#endif
- . = ALIGN(PAGE_SIZE);
- .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) {
- __per_cpu_start = .;
- *(.data.percpu.page_aligned)
- *(.data.percpu)
- *(.data.percpu.shared_aligned)
- __per_cpu_end = .;
- }
+ PERCPU(PAGE_SIZE)
. = ALIGN(PAGE_SIZE);
/* freed after init ends here */
diff --git a/arch/x86/kernel/vmlinux_64.lds.S b/arch/x86/kernel/vmlinux_64.lds.S
index 1a614c0..a09abb8 100644
--- a/arch/x86/kernel/vmlinux_64.lds.S
+++ b/arch/x86/kernel/vmlinux_64.lds.S
@@ -5,6 +5,7 @@
#define LOAD_OFFSET __START_KERNEL_map
#include <asm-generic/vmlinux.lds.h>
+#include <asm/asm-offsets.h>
#include <asm/page.h>
#undef i386 /* in case the preprocessor is a 32bit one */
@@ -13,12 +14,14 @@ OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(phys_startup_64)
jiffies_64 = jiffies;
-_proxy_pda = 1;
PHDRS {
text PT_LOAD FLAGS(5); /* R_E */
data PT_LOAD FLAGS(7); /* RWE */
user PT_LOAD FLAGS(7); /* RWE */
data.init PT_LOAD FLAGS(7); /* RWE */
+#ifdef CONFIG_SMP
+ percpu PT_LOAD FLAGS(7); /* RWE */
+#endif
note PT_NOTE FLAGS(0); /* ___ */
}
SECTIONS
@@ -208,14 +211,29 @@ SECTIONS
__initramfs_end = .;
#endif
+#ifdef CONFIG_SMP
+ /*
+ * percpu offsets are zero-based on SMP. PERCPU_VADDR() changes the
+ * output PHDR, so the next output section - __data_nosave - should
+ * switch it back to data.init. Also, pda should be at the head of
+ * percpu area. Preallocate it and define the percpu offset symbol
+ * so that it can be accessed as a percpu variable.
+ */
+ . = ALIGN(PAGE_SIZE);
+ PERCPU_VADDR_PREALLOC(0, :percpu, pda_size)
+ per_cpu____pda = __per_cpu_start;
+#else
PERCPU(PAGE_SIZE)
+#endif
. = ALIGN(PAGE_SIZE);
__init_end = .;
. = ALIGN(PAGE_SIZE);
__nosave_begin = .;
- .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) { *(.data.nosave) }
+ .data_nosave : AT(ADDR(.data_nosave) - LOAD_OFFSET) {
+ *(.data.nosave)
+ } :data.init /* switch back to data.init, see PERCPU_VADDR() above */
. = ALIGN(PAGE_SIZE);
__nosave_end = .;
diff --git a/arch/x86/kernel/x8664_ksyms_64.c b/arch/x86/kernel/x8664_ksyms_64.c
index 695e426..3909e3b 100644
--- a/arch/x86/kernel/x8664_ksyms_64.c
+++ b/arch/x86/kernel/x8664_ksyms_64.c
@@ -58,5 +58,3 @@ EXPORT_SYMBOL(__memcpy);
EXPORT_SYMBOL(empty_zero_page);
EXPORT_SYMBOL(init_level4_pgt);
EXPORT_SYMBOL(load_gs_index);
-
-EXPORT_SYMBOL(_proxy_pda);
diff --git a/arch/x86/mach-voyager/setup.c b/arch/x86/mach-voyager/setup.c
index a580b95..0ade625 100644
--- a/arch/x86/mach-voyager/setup.c
+++ b/arch/x86/mach-voyager/setup.c
@@ -9,6 +9,7 @@
#include <asm/e820.h>
#include <asm/io.h>
#include <asm/setup.h>
+#include <asm/cpu.h>
void __init pre_intr_init_hook(void)
{
diff --git a/arch/x86/mach-voyager/voyager_smp.c b/arch/x86/mach-voyager/voyager_smp.c
index 9840b7e..96f15b0 100644
--- a/arch/x86/mach-voyager/voyager_smp.c
+++ b/arch/x86/mach-voyager/voyager_smp.c
@@ -402,7 +402,7 @@ void __init find_smp_config(void)
VOYAGER_SUS_IN_CONTROL_PORT);
current_thread_info()->cpu = boot_cpu_id;
- x86_write_percpu(cpu_number, boot_cpu_id);
+ percpu_write(cpu_number, boot_cpu_id);
}
/*
@@ -531,6 +531,7 @@ static void __init do_boot_cpu(__u8 cpu)
stack_start.sp = (void *)idle->thread.sp;
init_gdt(cpu);
+ per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
per_cpu(current_task, cpu) = idle;
early_gdt_descr.address = (unsigned long)get_cpu_gdt_table(cpu);
irq_ctx_init(cpu);
@@ -1748,6 +1749,7 @@ static void __init voyager_smp_prepare_cpus(unsigned int max_cpus)
static void __cpuinit voyager_smp_prepare_boot_cpu(void)
{
init_gdt(smp_processor_id());
+ per_cpu(this_cpu_off, cpu) = __per_cpu_offset[cpu];
switch_to_new_gdt();
cpu_set(smp_processor_id(), cpu_online_map);
@@ -1780,7 +1782,7 @@ static void __init voyager_smp_cpus_done(unsigned int max_cpus)
void __init smp_setup_processor_id(void)
{
current_thread_info()->cpu = hard_smp_processor_id();
- x86_write_percpu(cpu_number, hard_smp_processor_id());
+ percpu_write(cpu_number, hard_smp_processor_id());
}
static void voyager_send_call_func(cpumask_t callmask)
diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c
index 9e268b6b..90dfae5 100644
--- a/arch/x86/mm/fault.c
+++ b/arch/x86/mm/fault.c
@@ -534,7 +534,7 @@ static int vmalloc_fault(unsigned long address)
happen within a race in page table update. In the later
case just flush. */
- pgd = pgd_offset(current->mm ?: &init_mm, address);
+ pgd = pgd_offset(current->active_mm, address);
pgd_ref = pgd_offset_k(address);
if (pgd_none(*pgd_ref))
return -1;
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 88f1b10..4a6989e 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -49,7 +49,6 @@
#include <asm/paravirt.h>
#include <asm/setup.h>
#include <asm/cacheflush.h>
-#include <asm/smp.h>
unsigned int __VMALLOC_RESERVE = 128 << 20;
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c
index e89d248..4cf30de 100644
--- a/arch/x86/mm/pageattr.c
+++ b/arch/x86/mm/pageattr.c
@@ -555,10 +555,12 @@ repeat:
if (!pte_val(old_pte)) {
if (!primary)
return 0;
- WARN(1, KERN_WARNING "CPA: called for zero pte. "
- "vaddr = %lx cpa->vaddr = %lx\n", address,
- *cpa->vaddr);
- return -EINVAL;
+
+ /*
+ * Special error value returned, indicating that the mapping
+ * did not exist at this address.
+ */
+ return -EFAULT;
}
if (level == PG_LEVEL_4K) {
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 85cbd3c..3be3990 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -333,11 +333,20 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
req_type & _PAGE_CACHE_MASK);
}
- is_range_ram = pagerange_is_ram(start, end);
- if (is_range_ram == 1)
- return reserve_ram_pages_type(start, end, req_type, new_type);
- else if (is_range_ram < 0)
- return -EINVAL;
+ /*
+ * For legacy reasons, some parts of the physical address range in the
+ * legacy 1MB region is treated as non-RAM (even when listed as RAM in
+ * the e820 tables). So we will track the memory attributes of this
+ * legacy 1MB region using the linear memtype_list always.
+ */
+ if (end >= ISA_END_ADDRESS) {
+ is_range_ram = pagerange_is_ram(start, end);
+ if (is_range_ram == 1)
+ return reserve_ram_pages_type(start, end, req_type,
+ new_type);
+ else if (is_range_ram < 0)
+ return -EINVAL;
+ }
new = kmalloc(sizeof(struct memtype), GFP_KERNEL);
if (!new)
@@ -437,11 +446,19 @@ int free_memtype(u64 start, u64 end)
if (is_ISA_range(start, end - 1))
return 0;
- is_range_ram = pagerange_is_ram(start, end);
- if (is_range_ram == 1)
- return free_ram_pages_type(start, end);
- else if (is_range_ram < 0)
- return -EINVAL;
+ /*
+ * For legacy reasons, some parts of the physical address range in the
+ * legacy 1MB region is treated as non-RAM (even when listed as RAM in
+ * the e820 tables). So we will track the memory attributes of this
+ * legacy 1MB region using the linear memtype_list always.
+ */
+ if (end >= ISA_END_ADDRESS) {
+ is_range_ram = pagerange_is_ram(start, end);
+ if (is_range_ram == 1)
+ return free_ram_pages_type(start, end);
+ else if (is_range_ram < 0)
+ return -EINVAL;
+ }
spin_lock(&memtype_lock);
list_for_each_entry(entry, &memtype_list, nd) {
@@ -505,6 +522,35 @@ static inline int range_is_allowed(unsigned long pfn, unsigned long size)
}
#endif /* CONFIG_STRICT_DEVMEM */
+/*
+ * Change the memory type for the physial address range in kernel identity
+ * mapping space if that range is a part of identity map.
+ */
+static int kernel_map_sync_memtype(u64 base, unsigned long size,
+ unsigned long flags)
+{
+ unsigned long id_sz;
+ int ret;
+
+ if (!pat_enabled || base >= __pa(high_memory))
+ return 0;
+
+ id_sz = (__pa(high_memory) < base + size) ?
+ __pa(high_memory) - base :
+ size;
+
+ ret = ioremap_change_attr((unsigned long)__va(base), id_sz, flags);
+ /*
+ * -EFAULT return means that the addr was not valid and did not have
+ * any identity mapping. That case is a success for
+ * kernel_map_sync_memtype.
+ */
+ if (ret == -EFAULT)
+ ret = 0;
+
+ return ret;
+}
+
int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
unsigned long size, pgprot_t *vma_prot)
{
@@ -555,9 +601,7 @@ int phys_mem_access_prot_allowed(struct file *file, unsigned long pfn,
if (retval < 0)
return 0;
- if (((pfn < max_low_pfn_mapped) ||
- (pfn >= (1UL<<(32 - PAGE_SHIFT)) && pfn < max_pfn_mapped)) &&
- ioremap_change_attr((unsigned long)__va(offset), size, flags) < 0) {
+ if (kernel_map_sync_memtype(offset, size, flags)) {
free_memtype(offset, offset + size);
printk(KERN_INFO
"%s:%d /dev/mem ioremap_change_attr failed %s for %Lx-%Lx\n",
@@ -601,12 +645,13 @@ void unmap_devmem(unsigned long pfn, unsigned long size, pgprot_t vma_prot)
* Reserved non RAM regions only and after successful reserve_memtype,
* this func also keeps identity mapping (if any) in sync with this new prot.
*/
-static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t vma_prot)
+static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t *vma_prot,
+ int strict_prot)
{
int is_ram = 0;
- int id_sz, ret;
+ int ret;
unsigned long flags;
- unsigned long want_flags = (pgprot_val(vma_prot) & _PAGE_CACHE_MASK);
+ unsigned long want_flags = (pgprot_val(*vma_prot) & _PAGE_CACHE_MASK);
is_ram = pagerange_is_ram(paddr, paddr + size);
@@ -625,26 +670,27 @@ static int reserve_pfn_range(u64 paddr, unsigned long size, pgprot_t vma_prot)
return ret;
if (flags != want_flags) {
- free_memtype(paddr, paddr + size);
- printk(KERN_ERR
- "%s:%d map pfn expected mapping type %s for %Lx-%Lx, got %s\n",
- current->comm, current->pid,
- cattr_name(want_flags),
- (unsigned long long)paddr,
- (unsigned long long)(paddr + size),
- cattr_name(flags));
- return -EINVAL;
+ if (strict_prot || !is_new_memtype_allowed(want_flags, flags)) {
+ free_memtype(paddr, paddr + size);
+ printk(KERN_ERR "%s:%d map pfn expected mapping type %s"
+ " for %Lx-%Lx, got %s\n",
+ current->comm, current->pid,
+ cattr_name(want_flags),
+ (unsigned long long)paddr,
+ (unsigned long long)(paddr + size),
+ cattr_name(flags));
+ return -EINVAL;
+ }
+ /*
+ * We allow returning different type than the one requested in
+ * non strict case.
+ */
+ *vma_prot = __pgprot((pgprot_val(*vma_prot) &
+ (~_PAGE_CACHE_MASK)) |
+ flags);
}
- /* Need to keep identity mapping in sync */
- if (paddr >= __pa(high_memory))
- return 0;
-
- id_sz = (__pa(high_memory) < paddr + size) ?
- __pa(high_memory) - paddr :
- size;
-
- if (ioremap_change_attr((unsigned long)__va(paddr), id_sz, flags) < 0) {
+ if (kernel_map_sync_memtype(paddr, size, flags)) {
free_memtype(paddr, paddr + size);
printk(KERN_ERR
"%s:%d reserve_pfn_range ioremap_change_attr failed %s "
@@ -689,6 +735,7 @@ int track_pfn_vma_copy(struct vm_area_struct *vma)
unsigned long vma_start = vma->vm_start;
unsigned long vma_end = vma->vm_end;
unsigned long vma_size = vma_end - vma_start;
+ pgprot_t pgprot;
if (!pat_enabled)
return 0;
@@ -702,7 +749,8 @@ int track_pfn_vma_copy(struct vm_area_struct *vma)
WARN_ON_ONCE(1);
return -EINVAL;
}
- return reserve_pfn_range(paddr, vma_size, __pgprot(prot));
+ pgprot = __pgprot(prot);
+ return reserve_pfn_range(paddr, vma_size, &pgprot, 1);
}
/* reserve entire vma page by page, using pfn and prot from pte */
@@ -710,7 +758,8 @@ int track_pfn_vma_copy(struct vm_area_struct *vma)
if (follow_phys(vma, vma_start + i, 0, &prot, &paddr))
continue;
- retval = reserve_pfn_range(paddr, PAGE_SIZE, __pgprot(prot));
+ pgprot = __pgprot(prot);
+ retval = reserve_pfn_range(paddr, PAGE_SIZE, &pgprot, 1);
if (retval)
goto cleanup_ret;
}
@@ -741,7 +790,7 @@ cleanup_ret:
* Note that this function can be called with caller trying to map only a
* subrange/page inside the vma.
*/
-int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t prot,
+int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t *prot,
unsigned long pfn, unsigned long size)
{
int retval = 0;
@@ -758,14 +807,14 @@ int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t prot,
if (is_linear_pfn_mapping(vma)) {
/* reserve the whole chunk starting from vm_pgoff */
paddr = (resource_size_t)vma->vm_pgoff << PAGE_SHIFT;
- return reserve_pfn_range(paddr, vma_size, prot);
+ return reserve_pfn_range(paddr, vma_size, prot, 0);
}
/* reserve page by page using pfn and size */
base_paddr = (resource_size_t)pfn << PAGE_SHIFT;
for (i = 0; i < size; i += PAGE_SIZE) {
paddr = base_paddr + i;
- retval = reserve_pfn_range(paddr, PAGE_SIZE, prot);
+ retval = reserve_pfn_range(paddr, PAGE_SIZE, prot, 0);
if (retval)
goto cleanup_ret;
}
diff --git a/arch/x86/pci/i386.c b/arch/x86/pci/i386.c
index f884740..5ead808 100644
--- a/arch/x86/pci/i386.c
+++ b/arch/x86/pci/i386.c
@@ -314,17 +314,7 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
return retval;
if (flags != new_flags) {
- /*
- * Do not fallback to certain memory types with certain
- * requested type:
- * - request is uncached, return cannot be write-back
- * - request is uncached, return cannot be write-combine
- * - request is write-combine, return cannot be write-back
- */
- if ((flags == _PAGE_CACHE_UC_MINUS &&
- (new_flags == _PAGE_CACHE_WB)) ||
- (flags == _PAGE_CACHE_WC &&
- new_flags == _PAGE_CACHE_WB)) {
+ if (!is_new_memtype_allowed(flags, new_flags)) {
free_memtype(addr, addr+len);
return -EINVAL;
}
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c
index bea2152..75b9413 100644
--- a/arch/x86/xen/enlighten.c
+++ b/arch/x86/xen/enlighten.c
@@ -634,35 +634,27 @@ static void xen_flush_tlb_single(unsigned long addr)
preempt_enable();
}
-static void xen_flush_tlb_others(const cpumask_t *cpus, struct mm_struct *mm,
- unsigned long va)
+static void xen_flush_tlb_others(const struct cpumask *cpus,
+ struct mm_struct *mm, unsigned long va)
{
struct {
struct mmuext_op op;
- cpumask_t mask;
+ DECLARE_BITMAP(mask, NR_CPUS);
} *args;
- cpumask_t cpumask = *cpus;
struct multicall_space mcs;
- /*
- * A couple of (to be removed) sanity checks:
- *
- * - current CPU must not be in mask
- * - mask must exist :)
- */
- BUG_ON(cpus_empty(cpumask));
- BUG_ON(cpu_isset(smp_processor_id(), cpumask));
+ BUG_ON(cpumask_empty(cpus));
BUG_ON(!mm);
- /* If a CPU which we ran on has gone down, OK. */
- cpus_and(cpumask, cpumask, cpu_online_map);
- if (cpus_empty(cpumask))
- return;
-
mcs = xen_mc_entry(sizeof(*args));
args = mcs.args;
- args->mask = cpumask;
- args->op.arg2.vcpumask = &args->mask;
+ args->op.arg2.vcpumask = to_cpumask(args->mask);
+
+ /* Remove us, and any offline CPUS. */
+ cpumask_and(to_cpumask(args->mask), cpus, cpu_online_mask);
+ cpumask_clear_cpu(smp_processor_id(), to_cpumask(args->mask));
+ if (unlikely(cpumask_empty(to_cpumask(args->mask))))
+ goto issue;
if (va == TLB_FLUSH_ALL) {
args->op.cmd = MMUEXT_TLB_FLUSH_MULTI;
@@ -673,6 +665,7 @@ static void xen_flush_tlb_others(const cpumask_t *cpus, struct mm_struct *mm,
MULTI_mmuext_op(mcs.mc, &args->op, 1, NULL, DOMID_SELF);
+issue:
xen_mc_issue(PARAVIRT_LAZY_MMU);
}
@@ -702,17 +695,17 @@ static void xen_write_cr0(unsigned long cr0)
static void xen_write_cr2(unsigned long cr2)
{
- x86_read_percpu(xen_vcpu)->arch.cr2 = cr2;
+ percpu_read(xen_vcpu)->arch.cr2 = cr2;
}
static unsigned long xen_read_cr2(void)
{
- return x86_read_percpu(xen_vcpu)->arch.cr2;
+ return percpu_read(xen_vcpu)->arch.cr2;
}
static unsigned long xen_read_cr2_direct(void)
{
- return x86_read_percpu(xen_vcpu_info.arch.cr2);
+ return percpu_read(xen_vcpu_info.arch.cr2);
}
static void xen_write_cr4(unsigned long cr4)
@@ -725,12 +718,12 @@ static void xen_write_cr4(unsigned long cr4)
static unsigned long xen_read_cr3(void)
{
- return x86_read_percpu(xen_cr3);
+ return percpu_read(xen_cr3);
}
static void set_current_cr3(void *v)
{
- x86_write_percpu(xen_current_cr3, (unsigned long)v);
+ percpu_write(xen_current_cr3, (unsigned long)v);
}
static void __xen_write_cr3(bool kernel, unsigned long cr3)
@@ -755,7 +748,7 @@ static void __xen_write_cr3(bool kernel, unsigned long cr3)
MULTI_mmuext_op(mcs.mc, op, 1, NULL, DOMID_SELF);
if (kernel) {
- x86_write_percpu(xen_cr3, cr3);
+ percpu_write(xen_cr3, cr3);
/* Update xen_current_cr3 once the batch has actually
been submitted. */
@@ -771,7 +764,7 @@ static void xen_write_cr3(unsigned long cr3)
/* Update while interrupts are disabled, so its atomic with
respect to ipis */
- x86_write_percpu(xen_cr3, cr3);
+ percpu_write(xen_cr3, cr3);
__xen_write_cr3(true, cr3);
@@ -1652,7 +1645,7 @@ asmlinkage void __init xen_start_kernel(void)
#ifdef CONFIG_X86_64
/* Disable until direct per-cpu data access. */
have_vcpu_info_placement = 0;
- x86_64_init_pda();
+ pda_init(0);
#endif
xen_smp_init();
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c
index bb04260..2e82714 100644
--- a/arch/x86/xen/irq.c
+++ b/arch/x86/xen/irq.c
@@ -39,7 +39,7 @@ static unsigned long xen_save_fl(void)
struct vcpu_info *vcpu;
unsigned long flags;
- vcpu = x86_read_percpu(xen_vcpu);
+ vcpu = percpu_read(xen_vcpu);
/* flag has opposite sense of mask */
flags = !vcpu->evtchn_upcall_mask;
@@ -62,7 +62,7 @@ static void xen_restore_fl(unsigned long flags)
make sure we're don't switch CPUs between getting the vcpu
pointer and updating the mask. */
preempt_disable();
- vcpu = x86_read_percpu(xen_vcpu);
+ vcpu = percpu_read(xen_vcpu);
vcpu->evtchn_upcall_mask = flags;
preempt_enable_no_resched();
@@ -83,7 +83,7 @@ static void xen_irq_disable(void)
make sure we're don't switch CPUs between getting the vcpu
pointer and updating the mask. */
preempt_disable();
- x86_read_percpu(xen_vcpu)->evtchn_upcall_mask = 1;
+ percpu_read(xen_vcpu)->evtchn_upcall_mask = 1;
preempt_enable_no_resched();
}
@@ -96,7 +96,7 @@ static void xen_irq_enable(void)
the caller is confused and is trying to re-enable interrupts
on an indeterminate processor. */
- vcpu = x86_read_percpu(xen_vcpu);
+ vcpu = percpu_read(xen_vcpu);
vcpu->evtchn_upcall_mask = 0;
/* Doesn't matter if we get preempted here, because any
diff --git a/arch/x86/xen/mmu.c b/arch/x86/xen/mmu.c
index 503c240..98cb986 100644
--- a/arch/x86/xen/mmu.c
+++ b/arch/x86/xen/mmu.c
@@ -1063,18 +1063,14 @@ static void drop_other_mm_ref(void *info)
struct mm_struct *mm = info;
struct mm_struct *active_mm;
-#ifdef CONFIG_X86_64
- active_mm = read_pda(active_mm);
-#else
- active_mm = __get_cpu_var(cpu_tlbstate).active_mm;
-#endif
+ active_mm = percpu_read(cpu_tlbstate.active_mm);
if (active_mm == mm)
leave_mm(smp_processor_id());
/* If this cpu still has a stale cr3 reference, then make sure
it has been flushed. */
- if (x86_read_percpu(xen_current_cr3) == __pa(mm->pgd)) {
+ if (percpu_read(xen_current_cr3) == __pa(mm->pgd)) {
load_cr3(swapper_pg_dir);
arch_flush_lazy_cpu_mode();
}
diff --git a/arch/x86/xen/multicalls.h b/arch/x86/xen/multicalls.h
index 8589382..e786fa7 100644
--- a/arch/x86/xen/multicalls.h
+++ b/arch/x86/xen/multicalls.h
@@ -39,7 +39,7 @@ static inline void xen_mc_issue(unsigned mode)
xen_mc_flush();
/* restore flags saved in xen_mc_batch */
- local_irq_restore(x86_read_percpu(xen_mc_irq_flags));
+ local_irq_restore(percpu_read(xen_mc_irq_flags));
}
/* Set up a callback to be called when the current batch is flushed */
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index c44e206..72c2eb9 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -50,11 +50,7 @@ static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id);
*/
static irqreturn_t xen_reschedule_interrupt(int irq, void *dev_id)
{
-#ifdef CONFIG_X86_32
- __get_cpu_var(irq_stat).irq_resched_count++;
-#else
- add_pda(irq_resched_count, 1);
-#endif
+ inc_irq_stat(irq_resched_count);
return IRQ_HANDLED;
}
@@ -78,7 +74,7 @@ static __cpuinit void cpu_bringup(void)
xen_setup_cpu_clockevents();
cpu_set(cpu, cpu_online_map);
- x86_write_percpu(cpu_state, CPU_ONLINE);
+ percpu_write(cpu_state, CPU_ONLINE);
wmb();
/* We can take interrupts now: we're officially "up". */
@@ -283,22 +279,11 @@ static int __cpuinit xen_cpu_up(unsigned int cpu)
struct task_struct *idle = idle_task(cpu);
int rc;
-#ifdef CONFIG_X86_64
- /* Allocate node local memory for AP pdas */
- WARN_ON(cpu == 0);
- if (cpu > 0) {
- rc = get_local_pda(cpu);
- if (rc)
- return rc;
- }
-#endif
-
+ per_cpu(current_task, cpu) = idle;
#ifdef CONFIG_X86_32
init_gdt(cpu);
- per_cpu(current_task, cpu) = idle;
irq_ctx_init(cpu);
#else
- cpu_pda(cpu)->pcurrent = idle;
clear_tsk_thread_flag(idle, TIF_FORK);
#endif
xen_setup_timer(cpu);
@@ -445,11 +430,7 @@ static irqreturn_t xen_call_function_interrupt(int irq, void *dev_id)
{
irq_enter();
generic_smp_call_function_interrupt();
-#ifdef CONFIG_X86_32
- __get_cpu_var(irq_stat).irq_call_count++;
-#else
- add_pda(irq_call_count, 1);
-#endif
+ inc_irq_stat(irq_call_count);
irq_exit();
return IRQ_HANDLED;
@@ -459,11 +440,7 @@ static irqreturn_t xen_call_function_single_interrupt(int irq, void *dev_id)
{
irq_enter();
generic_smp_call_function_single_interrupt();
-#ifdef CONFIG_X86_32
- __get_cpu_var(irq_stat).irq_call_count++;
-#else
- add_pda(irq_call_count, 1);
-#endif
+ inc_irq_stat(irq_call_count);
irq_exit();
return IRQ_HANDLED;
diff --git a/arch/x86/xen/xen-asm_64.S b/arch/x86/xen/xen-asm_64.S
index 05794c5..d6fc51f 100644
--- a/arch/x86/xen/xen-asm_64.S
+++ b/arch/x86/xen/xen-asm_64.S
@@ -17,6 +17,7 @@
#include <asm/processor-flags.h>
#include <asm/errno.h>
#include <asm/segment.h>
+#include <asm/percpu.h>
#include <xen/interface/xen.h>
@@ -28,12 +29,10 @@
#if 1
/*
- x86-64 does not yet support direct access to percpu variables
- via a segment override, so we just need to make sure this code
- never gets used
+ FIXME: x86_64 now can support direct access to percpu variables
+ via a segment override. Update xen accordingly.
*/
#define BUG ud2a
-#define PER_CPU_VAR(var, off) 0xdeadbeef
#endif
/*
@@ -45,14 +44,14 @@ ENTRY(xen_irq_enable_direct)
BUG
/* Unmask events */
- movb $0, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask)
+ movb $0, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
/* Preempt here doesn't matter because that will deal with
any pending interrupts. The pending check may end up being
run on the wrong CPU, but that doesn't hurt. */
/* Test for pending */
- testb $0xff, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_pending)
+ testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending
jz 1f
2: call check_events
@@ -69,7 +68,7 @@ ENDPATCH(xen_irq_enable_direct)
ENTRY(xen_irq_disable_direct)
BUG
- movb $1, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask)
+ movb $1, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
ENDPATCH(xen_irq_disable_direct)
ret
ENDPROC(xen_irq_disable_direct)
@@ -87,7 +86,7 @@ ENDPATCH(xen_irq_disable_direct)
ENTRY(xen_save_fl_direct)
BUG
- testb $0xff, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask)
+ testb $0xff, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
setz %ah
addb %ah,%ah
ENDPATCH(xen_save_fl_direct)
@@ -107,13 +106,13 @@ ENTRY(xen_restore_fl_direct)
BUG
testb $X86_EFLAGS_IF>>8, %ah
- setz PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_mask)
+ setz PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_mask
/* Preempt here doesn't matter because that will deal with
any pending interrupts. The pending check may end up being
run on the wrong CPU, but that doesn't hurt. */
/* check for unmasked and pending */
- cmpw $0x0001, PER_CPU_VAR(xen_vcpu_info, XEN_vcpu_info_pending)
+ cmpw $0x0001, PER_CPU_VAR(xen_vcpu_info) + XEN_vcpu_info_pending
jz 1f
2: call check_events
1:
@@ -195,11 +194,11 @@ RELOC(xen_sysexit, 1b+1)
ENTRY(xen_sysret64)
/* We're already on the usermode stack at this point, but still
with the kernel gs, so we can easily switch back */
- movq %rsp, %gs:pda_oldrsp
- movq %gs:pda_kernelstack,%rsp
+ movq %rsp, PER_CPU_VAR(old_rsp)
+ movq PER_CPU_VAR(kernel_stack),%rsp
pushq $__USER_DS
- pushq %gs:pda_oldrsp
+ pushq PER_CPU_VAR(old_rsp)
pushq %r11
pushq $__USER_CS
pushq %rcx
@@ -212,11 +211,11 @@ RELOC(xen_sysret64, 1b+1)
ENTRY(xen_sysret32)
/* We're already on the usermode stack at this point, but still
with the kernel gs, so we can easily switch back */
- movq %rsp, %gs:pda_oldrsp
- movq %gs:pda_kernelstack, %rsp
+ movq %rsp, PER_CPU_VAR(old_rsp)
+ movq PER_CPU_VAR(kernel_stack), %rsp
pushq $__USER32_DS
- pushq %gs:pda_oldrsp
+ pushq PER_CPU_VAR(old_rsp)
pushq %r11
pushq $__USER32_CS
pushq %rcx
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 0eae9b4..5a4aad1 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -1013,9 +1013,12 @@ next_sg:
qc->cursg_ofs = 0;
}
- /* consumed can be larger than count only for the last transfer */
- WARN_ON_ONCE(qc->cursg && count != consumed);
-
+ /*
+ * There used to be a WARN_ON_ONCE(qc->cursg && count != consumed);
+ * Unfortunately __atapi_pio_bytes doesn't know enough to do the WARN
+ * check correctly as it doesn't know if it is the last request being
+ * made. Somebody should implement a proper sanity check.
+ */
if (bytes)
goto next_sg;
return 0;
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index f828a29..f1bb2f9 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -80,7 +80,7 @@
#define DRV_NAME "pata_it821x"
-#define DRV_VERSION "0.4.0"
+#define DRV_VERSION "0.4.2"
struct it821x_dev
{
@@ -494,8 +494,6 @@ static int it821x_smart_set_mode(struct ata_link *link, struct ata_device **unus
* special. In our case we need to lock the sector count to avoid
* blowing the brains out of the firmware with large LBA48 requests
*
- * FIXME: When FUA appears we need to block FUA too. And SMART and
- * basically we need to filter commands for this chip.
*/
static void it821x_dev_config(struct ata_device *adev)
@@ -890,6 +888,13 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
.flags = ATA_FLAG_SLAVE_POSS,
.pio_mask = 0x1f,
.mwdma_mask = 0x07,
+ .udma_mask = ATA_UDMA6,
+ .port_ops = &it821x_rdc_port_ops
+ };
+ static const struct ata_port_info info_rdc_11 = {
+ .flags = ATA_FLAG_SLAVE_POSS,
+ .pio_mask = 0x1f,
+ .mwdma_mask = 0x07,
/* No UDMA */
.port_ops = &it821x_rdc_port_ops
};
@@ -903,7 +908,11 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
return rc;
if (pdev->vendor == PCI_VENDOR_ID_RDC) {
- ppi[0] = &info_rdc;
+ /* Deal with Vortex86SX */
+ if (pdev->revision == 0x11)
+ ppi[0] = &info_rdc_11;
+ else
+ ppi[0] = &info_rdc;
} else {
/* Force the card into bypass mode if so requested */
if (it8212_noraid) {
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 719ee5c..5b257a5 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -107,7 +107,7 @@ static SYSDEV_ATTR(crash_notes, 0400, show_crash_notes, NULL);
/*
* Print cpu online, possible, present, and system maps
*/
-static ssize_t print_cpus_map(char *buf, cpumask_t *map)
+static ssize_t print_cpus_map(char *buf, const struct cpumask *map)
{
int n = cpulist_scnprintf(buf, PAGE_SIZE-2, map);
diff --git a/drivers/base/topology.c b/drivers/base/topology.c
index a778fb5..bf6b132 100644
--- a/drivers/base/topology.c
+++ b/drivers/base/topology.c
@@ -31,7 +31,10 @@
#include <linux/hardirq.h>
#include <linux/topology.h>
-#define define_one_ro(_name) \
+#define define_one_ro_named(_name, _func) \
+static SYSDEV_ATTR(_name, 0444, _func, NULL)
+
+#define define_one_ro(_name) \
static SYSDEV_ATTR(_name, 0444, show_##_name, NULL)
#define define_id_show_func(name) \
@@ -42,8 +45,8 @@ static ssize_t show_##name(struct sys_device *dev, \
return sprintf(buf, "%d\n", topology_##name(cpu)); \
}
-#if defined(topology_thread_siblings) || defined(topology_core_siblings)
-static ssize_t show_cpumap(int type, cpumask_t *mask, char *buf)
+#if defined(topology_thread_cpumask) || defined(topology_core_cpumask)
+static ssize_t show_cpumap(int type, const struct cpumask *mask, char *buf)
{
ptrdiff_t len = PTR_ALIGN(buf + PAGE_SIZE - 1, PAGE_SIZE) - buf;
int n = 0;
@@ -65,7 +68,7 @@ static ssize_t show_##name(struct sys_device *dev, \
struct sysdev_attribute *attr, char *buf) \
{ \
unsigned int cpu = dev->id; \
- return show_cpumap(0, &(topology_##name(cpu)), buf); \
+ return show_cpumap(0, topology_##name(cpu), buf); \
}
#define define_siblings_show_list(name) \
@@ -74,7 +77,7 @@ static ssize_t show_##name##_list(struct sys_device *dev, \
char *buf) \
{ \
unsigned int cpu = dev->id; \
- return show_cpumap(1, &(topology_##name(cpu)), buf); \
+ return show_cpumap(1, topology_##name(cpu), buf); \
}
#else
@@ -82,9 +85,7 @@ static ssize_t show_##name##_list(struct sys_device *dev, \
static ssize_t show_##name(struct sys_device *dev, \
struct sysdev_attribute *attr, char *buf) \
{ \
- unsigned int cpu = dev->id; \
- cpumask_t mask = topology_##name(cpu); \
- return show_cpumap(0, &mask, buf); \
+ return show_cpumap(0, topology_##name(dev->id), buf); \
}
#define define_siblings_show_list(name) \
@@ -92,9 +93,7 @@ static ssize_t show_##name##_list(struct sys_device *dev, \
struct sysdev_attribute *attr, \
char *buf) \
{ \
- unsigned int cpu = dev->id; \
- cpumask_t mask = topology_##name(cpu); \
- return show_cpumap(1, &mask, buf); \
+ return show_cpumap(1, topology_##name(dev->id), buf); \
}
#endif
@@ -107,13 +106,13 @@ define_one_ro(physical_package_id);
define_id_show_func(core_id);
define_one_ro(core_id);
-define_siblings_show_func(thread_siblings);
-define_one_ro(thread_siblings);
-define_one_ro(thread_siblings_list);
+define_siblings_show_func(thread_cpumask);
+define_one_ro_named(thread_siblings, show_thread_cpumask);
+define_one_ro_named(thread_siblings_list, show_thread_cpumask_list);
-define_siblings_show_func(core_siblings);
-define_one_ro(core_siblings);
-define_one_ro(core_siblings_list);
+define_siblings_show_func(core_cpumask);
+define_one_ro_named(core_siblings, show_core_cpumask);
+define_one_ro_named(core_siblings_list, show_core_cpumask_list);
static struct attribute *default_attrs[] = {
&attr_physical_package_id.attr,
diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 4b1d4ac..8df436f 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -156,7 +156,7 @@ static volatile int fdc_busy = -1;
static volatile int fdc_nested;
static DECLARE_WAIT_QUEUE_HEAD(fdc_wait);
-static DECLARE_WAIT_QUEUE_HEAD(motor_wait);
+static DECLARE_COMPLETION(motor_on_completion);
static volatile int selected = -1; /* currently selected drive */
@@ -184,8 +184,7 @@ static unsigned char mfmencode[16]={
static unsigned char mfmdecode[128];
/* floppy internal millisecond timer stuff */
-static volatile int ms_busy = -1;
-static DECLARE_WAIT_QUEUE_HEAD(ms_wait);
+static DECLARE_COMPLETION(ms_wait_completion);
#define MS_TICKS ((amiga_eclock+50)/1000)
/*
@@ -211,8 +210,7 @@ static int fd_device[4] = { 0, 0, 0, 0 };
static irqreturn_t ms_isr(int irq, void *dummy)
{
- ms_busy = -1;
- wake_up(&ms_wait);
+ complete(&ms_wait_completion);
return IRQ_HANDLED;
}
@@ -220,19 +218,17 @@ static irqreturn_t ms_isr(int irq, void *dummy)
A more generic routine would do a schedule a la timer.device */
static void ms_delay(int ms)
{
- unsigned long flags;
int ticks;
+ static DEFINE_MUTEX(mutex);
+
if (ms > 0) {
- local_irq_save(flags);
- while (ms_busy == 0)
- sleep_on(&ms_wait);
- ms_busy = 0;
- local_irq_restore(flags);
+ mutex_lock(&mutex);
ticks = MS_TICKS*ms-1;
ciaa.tblo=ticks%256;
ciaa.tbhi=ticks/256;
ciaa.crb=0x19; /*count eclock, force load, one-shoot, start */
- sleep_on(&ms_wait);
+ wait_for_completion(&ms_wait_completion);
+ mutex_unlock(&mutex);
}
}
@@ -254,8 +250,7 @@ static void get_fdc(int drive)
printk("get_fdc: drive %d fdc_busy %d fdc_nested %d\n",drive,fdc_busy,fdc_nested);
#endif
local_irq_save(flags);
- while (!try_fdc(drive))
- sleep_on(&fdc_wait);
+ wait_event(fdc_wait, try_fdc(drive));
fdc_busy = drive;
fdc_nested++;
local_irq_restore(flags);
@@ -330,7 +325,7 @@ static void fd_deselect (int drive)
static void motor_on_callback(unsigned long nr)
{
if (!(ciaa.pra & DSKRDY) || --on_attempts == 0) {
- wake_up (&motor_wait);
+ complete_all(&motor_on_completion);
} else {
motor_on_timer.expires = jiffies + HZ/10;
add_timer(&motor_on_timer);
@@ -347,11 +342,12 @@ static int fd_motor_on(int nr)
unit[nr].motor = 1;
fd_select(nr);
+ INIT_COMPLETION(motor_on_completion);
motor_on_timer.data = nr;
mod_timer(&motor_on_timer, jiffies + HZ/2);
on_attempts = 10;
- sleep_on (&motor_wait);
+ wait_for_completion(&motor_on_completion);
fd_deselect(nr);
}
@@ -582,8 +578,7 @@ static void raw_read(int drive)
{
drive&=3;
get_fdc(drive);
- while (block_flag)
- sleep_on(&wait_fd_block);
+ wait_event(wait_fd_block, !block_flag);
fd_select(drive);
/* setup adkcon bits correctly */
custom.adkcon = ADK_MSBSYNC;
@@ -598,8 +593,7 @@ static void raw_read(int drive)
block_flag = 1;
- while (block_flag)
- sleep_on (&wait_fd_block);
+ wait_event(wait_fd_block, !block_flag);
custom.dsklen = 0;
fd_deselect(drive);
@@ -616,8 +610,7 @@ static int raw_write(int drive)
rel_fdc();
return 0;
}
- while (block_flag)
- sleep_on(&wait_fd_block);
+ wait_event(wait_fd_block, !block_flag);
fd_select(drive);
/* clear adkcon bits */
custom.adkcon = ADK_PRECOMP1|ADK_PRECOMP0|ADK_WORDSYNC|ADK_MSBSYNC;
@@ -1294,8 +1287,7 @@ static int non_int_flush_track (unsigned long nr)
writepending = 0;
return 0;
}
- while (block_flag == 2)
- sleep_on (&wait_fd_block);
+ wait_event(wait_fd_block, block_flag != 2);
}
else {
local_irq_restore(flags);
diff --git a/drivers/char/amiserial.c b/drivers/char/amiserial.c
index 4e0cfde..a58869e 100644
--- a/drivers/char/amiserial.c
+++ b/drivers/char/amiserial.c
@@ -1963,6 +1963,7 @@ static int __init rs_init(void)
{
unsigned long flags;
struct serial_state * state;
+ int error;
if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_SERIAL))
return -ENODEV;
@@ -1975,8 +1976,11 @@ static int __init rs_init(void)
* We request SERDAT and SERPER only, because the serial registers are
* too spreaded over the custom register space
*/
- if (!request_mem_region(CUSTOM_PHYSADDR+0x30, 4, "amiserial [Paula]"))
- return -EBUSY;
+ if (!request_mem_region(CUSTOM_PHYSADDR+0x30, 4,
+ "amiserial [Paula]")) {
+ error = -EBUSY;
+ goto fail_put_tty_driver;
+ }
IRQ_ports = NULL;
@@ -1997,8 +2001,9 @@ static int __init rs_init(void)
serial_driver->flags = TTY_DRIVER_REAL_RAW;
tty_set_operations(serial_driver, &serial_ops);
- if (tty_register_driver(serial_driver))
- panic("Couldn't register serial driver\n");
+ error = tty_register_driver(serial_driver);
+ if (error)
+ goto fail_release_mem_region;
state = rs_table;
state->magic = SSTATE_MAGIC;
@@ -2024,8 +2029,14 @@ static int __init rs_init(void)
local_irq_save(flags);
/* set ISRs, and then disable the rx interrupts */
- request_irq(IRQ_AMIGA_TBE, ser_tx_int, 0, "serial TX", state);
- request_irq(IRQ_AMIGA_RBF, ser_rx_int, IRQF_DISABLED, "serial RX", state);
+ error = request_irq(IRQ_AMIGA_TBE, ser_tx_int, 0, "serial TX", state);
+ if (error)
+ goto fail_unregister;
+
+ error = request_irq(IRQ_AMIGA_RBF, ser_rx_int, IRQF_DISABLED,
+ "serial RX", state);
+ if (error)
+ goto fail_free_irq;
/* turn off Rx and Tx interrupts */
custom.intena = IF_RBF | IF_TBE;
@@ -2045,6 +2056,16 @@ static int __init rs_init(void)
ciab.ddra &= ~(SER_DCD | SER_CTS | SER_DSR); /* inputs */
return 0;
+
+fail_free_irq:
+ free_irq(IRQ_AMIGA_TBE, state);
+fail_unregister:
+ tty_unregister_driver(serial_driver);
+fail_release_mem_region:
+ release_mem_region(CUSTOM_PHYSADDR+0x30, 4);
+fail_put_tty_driver:
+ put_tty_driver(serial_driver);
+ return error;
}
static __exit void rs_exit(void)
@@ -2064,6 +2085,9 @@ static __exit void rs_exit(void)
kfree(info);
}
+ free_irq(IRQ_AMIGA_TBE, rs_table);
+ free_irq(IRQ_AMIGA_RBF, rs_table);
+
release_mem_region(CUSTOM_PHYSADDR+0x30, 4);
}
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 146c976..31038a0 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -230,9 +230,7 @@ static void pty_set_termios(struct tty_struct *tty,
/**
* pty_do_resize - resize event
* @tty: tty being resized
- * @real_tty: real tty (not the same as tty if using a pty/tty pair)
- * @rows: rows (character)
- * @cols: cols (character)
+ * @ws: window size being set.
*
* Update the termios variables and send the neccessary signals to
* peform a terminal resize correctly
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c
index 33872a2..33a2b53 100644
--- a/drivers/char/ser_a2232.c
+++ b/drivers/char/ser_a2232.c
@@ -718,6 +718,7 @@ static int __init a2232board_init(void)
u_char *from;
volatile u_char *to;
volatile struct a2232memory *mem;
+ int error, i;
#ifdef CONFIG_SMP
return -ENODEV; /* This driver is not SMP aware. Is there an SMP ZorroII-bus-machine? */
@@ -797,8 +798,15 @@ static int __init a2232board_init(void)
*/
if (a2232_init_drivers()) return -ENODEV; // maybe we should use a different -Exxx?
- request_irq(IRQ_AMIGA_VERTB, a2232_vbl_inter, 0, "A2232 serial VBL", a2232_driver_ID);
- return 0;
+ error = request_irq(IRQ_AMIGA_VERTB, a2232_vbl_inter, 0,
+ "A2232 serial VBL", a2232_driver_ID);
+ if (error) {
+ for (i = 0; i < nr_a2232; i++)
+ zorro_release_device(zd_a2232[i]);
+ tty_unregister_driver(a2232_driver);
+ put_tty_driver(a2232_driver);
+ }
+ return error;
}
static void __exit a2232board_exit(void)
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c
index 0e8234b..994e1a5 100644
--- a/drivers/char/vme_scc.c
+++ b/drivers/char/vme_scc.c
@@ -198,6 +198,7 @@ static void scc_init_portstructs(void)
static int mvme147_scc_init(void)
{
struct scc_port *port;
+ int error;
printk(KERN_INFO "SCC: MVME147 Serial Driver\n");
/* Init channel A */
@@ -207,14 +208,23 @@ static int mvme147_scc_init(void)
port->datap = port->ctrlp + 1;
port->port_a = &scc_ports[0];
port->port_b = &scc_ports[1];
- request_irq(MVME147_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED,
+ error = request_irq(MVME147_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED,
"SCC-A TX", port);
- request_irq(MVME147_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED,
+ if (error)
+ goto fail;
+ error = request_irq(MVME147_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED,
"SCC-A status", port);
- request_irq(MVME147_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED,
+ if (error)
+ goto fail_free_a_tx;
+ error = request_irq(MVME147_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED,
"SCC-A RX", port);
- request_irq(MVME147_IRQ_SCCA_SPCOND, scc_spcond_int, IRQF_DISABLED,
- "SCC-A special cond", port);
+ if (error)
+ goto fail_free_a_stat;
+ error = request_irq(MVME147_IRQ_SCCA_SPCOND, scc_spcond_int,
+ IRQF_DISABLED, "SCC-A special cond", port);
+ if (error)
+ goto fail_free_a_rx;
+
{
SCC_ACCESS_INIT(port);
@@ -234,14 +244,23 @@ static int mvme147_scc_init(void)
port->datap = port->ctrlp + 1;
port->port_a = &scc_ports[0];
port->port_b = &scc_ports[1];
- request_irq(MVME147_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED,
+ error = request_irq(MVME147_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED,
"SCC-B TX", port);
- request_irq(MVME147_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED,
+ if (error)
+ goto fail_free_a_spcond;
+ error = request_irq(MVME147_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED,
"SCC-B status", port);
- request_irq(MVME147_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED,
+ if (error)
+ goto fail_free_b_tx;
+ error = request_irq(MVME147_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED,
"SCC-B RX", port);
- request_irq(MVME147_IRQ_SCCB_SPCOND, scc_spcond_int, IRQF_DISABLED,
- "SCC-B special cond", port);
+ if (error)
+ goto fail_free_b_stat;
+ error = request_irq(MVME147_IRQ_SCCB_SPCOND, scc_spcond_int,
+ IRQF_DISABLED, "SCC-B special cond", port);
+ if (error)
+ goto fail_free_b_rx;
+
{
SCC_ACCESS_INIT(port);
@@ -257,6 +276,23 @@ static int mvme147_scc_init(void)
scc_init_drivers();
return 0;
+
+fail_free_b_rx:
+ free_irq(MVME147_IRQ_SCCB_RX, port);
+fail_free_b_stat:
+ free_irq(MVME147_IRQ_SCCB_STAT, port);
+fail_free_b_tx:
+ free_irq(MVME147_IRQ_SCCB_TX, port);
+fail_free_a_spcond:
+ free_irq(MVME147_IRQ_SCCA_SPCOND, port);
+fail_free_a_rx:
+ free_irq(MVME147_IRQ_SCCA_RX, port);
+fail_free_a_stat:
+ free_irq(MVME147_IRQ_SCCA_STAT, port);
+fail_free_a_tx:
+ free_irq(MVME147_IRQ_SCCA_TX, port);
+fail:
+ return error;
}
#endif
@@ -265,6 +301,7 @@ static int mvme147_scc_init(void)
static int mvme162_scc_init(void)
{
struct scc_port *port;
+ int error;
if (!(mvme16x_config & MVME16x_CONFIG_GOT_SCCA))
return (-ENODEV);
@@ -277,14 +314,23 @@ static int mvme162_scc_init(void)
port->datap = port->ctrlp + 2;
port->port_a = &scc_ports[0];
port->port_b = &scc_ports[1];
- request_irq(MVME162_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED,
+ error = request_irq(MVME162_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED,
"SCC-A TX", port);
- request_irq(MVME162_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED,
+ if (error)
+ goto fail;
+ error = request_irq(MVME162_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED,
"SCC-A status", port);
- request_irq(MVME162_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED,
+ if (error)
+ goto fail_free_a_tx;
+ error = request_irq(MVME162_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED,
"SCC-A RX", port);
- request_irq(MVME162_IRQ_SCCA_SPCOND, scc_spcond_int, IRQF_DISABLED,
- "SCC-A special cond", port);
+ if (error)
+ goto fail_free_a_stat;
+ error = request_irq(MVME162_IRQ_SCCA_SPCOND, scc_spcond_int,
+ IRQF_DISABLED, "SCC-A special cond", port);
+ if (error)
+ goto fail_free_a_rx;
+
{
SCC_ACCESS_INIT(port);
@@ -304,14 +350,22 @@ static int mvme162_scc_init(void)
port->datap = port->ctrlp + 2;
port->port_a = &scc_ports[0];
port->port_b = &scc_ports[1];
- request_irq(MVME162_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED,
+ error = request_irq(MVME162_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED,
"SCC-B TX", port);
- request_irq(MVME162_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED,
+ if (error)
+ goto fail_free_a_spcond;
+ error = request_irq(MVME162_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED,
"SCC-B status", port);
- request_irq(MVME162_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED,
+ if (error)
+ goto fail_free_b_tx;
+ error = request_irq(MVME162_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED,
"SCC-B RX", port);
- request_irq(MVME162_IRQ_SCCB_SPCOND, scc_spcond_int, IRQF_DISABLED,
- "SCC-B special cond", port);
+ if (error)
+ goto fail_free_b_stat;
+ error = request_irq(MVME162_IRQ_SCCB_SPCOND, scc_spcond_int,
+ IRQF_DISABLED, "SCC-B special cond", port);
+ if (error)
+ goto fail_free_b_rx;
{
SCC_ACCESS_INIT(port); /* Either channel will do */
@@ -328,6 +382,23 @@ static int mvme162_scc_init(void)
scc_init_drivers();
return 0;
+
+fail_free_b_rx:
+ free_irq(MVME162_IRQ_SCCB_RX, port);
+fail_free_b_stat:
+ free_irq(MVME162_IRQ_SCCB_STAT, port);
+fail_free_b_tx:
+ free_irq(MVME162_IRQ_SCCB_TX, port);
+fail_free_a_spcond:
+ free_irq(MVME162_IRQ_SCCA_SPCOND, port);
+fail_free_a_rx:
+ free_irq(MVME162_IRQ_SCCA_RX, port);
+fail_free_a_stat:
+ free_irq(MVME162_IRQ_SCCA_STAT, port);
+fail_free_a_tx:
+ free_irq(MVME162_IRQ_SCCA_TX, port);
+fail:
+ return error;
}
#endif
@@ -336,6 +407,7 @@ static int mvme162_scc_init(void)
static int bvme6000_scc_init(void)
{
struct scc_port *port;
+ int error;
printk(KERN_INFO "SCC: BVME6000 Serial Driver\n");
/* Init channel A */
@@ -345,14 +417,23 @@ static int bvme6000_scc_init(void)
port->datap = port->ctrlp + 4;
port->port_a = &scc_ports[0];
port->port_b = &scc_ports[1];
- request_irq(BVME_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED,
+ error = request_irq(BVME_IRQ_SCCA_TX, scc_tx_int, IRQF_DISABLED,
"SCC-A TX", port);
- request_irq(BVME_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED,
+ if (error)
+ goto fail;
+ error = request_irq(BVME_IRQ_SCCA_STAT, scc_stat_int, IRQF_DISABLED,
"SCC-A status", port);
- request_irq(BVME_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED,
+ if (error)
+ goto fail_free_a_tx;
+ error = request_irq(BVME_IRQ_SCCA_RX, scc_rx_int, IRQF_DISABLED,
"SCC-A RX", port);
- request_irq(BVME_IRQ_SCCA_SPCOND, scc_spcond_int, IRQF_DISABLED,
- "SCC-A special cond", port);
+ if (error)
+ goto fail_free_a_stat;
+ error = request_irq(BVME_IRQ_SCCA_SPCOND, scc_spcond_int,
+ IRQF_DISABLED, "SCC-A special cond", port);
+ if (error)
+ goto fail_free_a_rx;
+
{
SCC_ACCESS_INIT(port);
@@ -372,14 +453,22 @@ static int bvme6000_scc_init(void)
port->datap = port->ctrlp + 4;
port->port_a = &scc_ports[0];
port->port_b = &scc_ports[1];
- request_irq(BVME_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED,
+ error = request_irq(BVME_IRQ_SCCB_TX, scc_tx_int, IRQF_DISABLED,
"SCC-B TX", port);
- request_irq(BVME_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED,
+ if (error)
+ goto fail_free_a_spcond;
+ error = request_irq(BVME_IRQ_SCCB_STAT, scc_stat_int, IRQF_DISABLED,
"SCC-B status", port);
- request_irq(BVME_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED,
+ if (error)
+ goto fail_free_b_tx;
+ error = request_irq(BVME_IRQ_SCCB_RX, scc_rx_int, IRQF_DISABLED,
"SCC-B RX", port);
- request_irq(BVME_IRQ_SCCB_SPCOND, scc_spcond_int, IRQF_DISABLED,
- "SCC-B special cond", port);
+ if (error)
+ goto fail_free_b_stat;
+ error = request_irq(BVME_IRQ_SCCB_SPCOND, scc_spcond_int,
+ IRQF_DISABLED, "SCC-B special cond", port);
+ if (error)
+ goto fail_free_b_rx;
{
SCC_ACCESS_INIT(port); /* Either channel will do */
@@ -393,6 +482,23 @@ static int bvme6000_scc_init(void)
scc_init_drivers();
return 0;
+
+fail:
+ free_irq(BVME_IRQ_SCCA_STAT, port);
+fail_free_a_tx:
+ free_irq(BVME_IRQ_SCCA_RX, port);
+fail_free_a_stat:
+ free_irq(BVME_IRQ_SCCA_SPCOND, port);
+fail_free_a_rx:
+ free_irq(BVME_IRQ_SCCB_TX, port);
+fail_free_a_spcond:
+ free_irq(BVME_IRQ_SCCB_STAT, port);
+fail_free_b_tx:
+ free_irq(BVME_IRQ_SCCB_RX, port);
+fail_free_b_stat:
+ free_irq(BVME_IRQ_SCCB_SPCOND, port);
+fail_free_b_rx:
+ return error;
}
#endif
diff --git a/drivers/dio/dio-sysfs.c b/drivers/dio/dio-sysfs.c
index f464630..ee1a3b5 100644
--- a/drivers/dio/dio-sysfs.c
+++ b/drivers/dio/dio-sysfs.c
@@ -58,20 +58,25 @@ static ssize_t dio_show_resource(struct device *dev, struct device_attribute *at
struct dio_dev *d = to_dio_dev(dev);
return sprintf(buf, "0x%08lx 0x%08lx 0x%08lx\n",
- dio_resource_start(d), dio_resource_end(d),
+ (unsigned long)dio_resource_start(d),
+ (unsigned long)dio_resource_end(d),
dio_resource_flags(d));
}
static DEVICE_ATTR(resource, S_IRUGO, dio_show_resource, NULL);
-void dio_create_sysfs_dev_files(struct dio_dev *d)
+int dio_create_sysfs_dev_files(struct dio_dev *d)
{
struct device *dev = &d->dev;
+ int error;
/* current configuration's attributes */
- device_create_file(dev, &dev_attr_id);
- device_create_file(dev, &dev_attr_ipl);
- device_create_file(dev, &dev_attr_secid);
- device_create_file(dev, &dev_attr_name);
- device_create_file(dev, &dev_attr_resource);
+ if ((error = device_create_file(dev, &dev_attr_id)) ||
+ (error = device_create_file(dev, &dev_attr_ipl)) ||
+ (error = device_create_file(dev, &dev_attr_secid)) ||
+ (error = device_create_file(dev, &dev_attr_name)) ||
+ (error = device_create_file(dev, &dev_attr_resource)))
+ return error;
+
+ return 0;
}
diff --git a/drivers/dio/dio.c b/drivers/dio/dio.c
index 07f274f..10c3c49 100644
--- a/drivers/dio/dio.c
+++ b/drivers/dio/dio.c
@@ -173,6 +173,7 @@ static int __init dio_init(void)
mm_segment_t fs;
int i;
struct dio_dev *dev;
+ int error;
if (!MACH_IS_HP300)
return 0;
@@ -182,7 +183,11 @@ static int __init dio_init(void)
/* Initialize the DIO bus */
INIT_LIST_HEAD(&dio_bus.devices);
strcpy(dio_bus.dev.bus_id, "dio");
- device_register(&dio_bus.dev);
+ error = device_register(&dio_bus.dev);
+ if (error) {
+ pr_err("DIO: Error registering dio_bus\n");
+ return error;
+ }
/* Request all resources */
dio_bus.num_resources = (hp300_model == HP_320 ? 1 : 2);
@@ -252,8 +257,15 @@ static int __init dio_init(void)
if (scode >= DIOII_SCBASE)
iounmap(va);
- device_register(&dev->dev);
- dio_create_sysfs_dev_files(dev);
+ error = device_register(&dev->dev);
+ if (error) {
+ pr_err("DIO: Error registering device %s\n",
+ dev->name);
+ continue;
+ }
+ error = dio_create_sysfs_dev_files(dev);
+ if (error)
+ dev_err(&dev->dev, "Error creating sysfs files\n");
}
return 0;
}
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c
index 777fba4..3009e01 100644
--- a/drivers/firmware/dcdbas.c
+++ b/drivers/firmware/dcdbas.c
@@ -244,7 +244,7 @@ static ssize_t host_control_on_shutdown_store(struct device *dev,
*/
int dcdbas_smi_request(struct smi_cmd *smi_cmd)
{
- cpumask_t old_mask;
+ cpumask_var_t old_mask;
int ret = 0;
if (smi_cmd->magic != SMI_CMD_MAGIC) {
@@ -254,8 +254,11 @@ int dcdbas_smi_request(struct smi_cmd *smi_cmd)
}
/* SMI requires CPU 0 */
- old_mask = current->cpus_allowed;
- set_cpus_allowed_ptr(current, &cpumask_of_cpu(0));
+ if (!alloc_cpumask_var(&old_mask, GFP_KERNEL))
+ return -ENOMEM;
+
+ cpumask_copy(old_mask, &current->cpus_allowed);
+ set_cpus_allowed_ptr(current, cpumask_of(0));
if (smp_processor_id() != 0) {
dev_dbg(&dcdbas_pdev->dev, "%s: failed to get CPU 0\n",
__func__);
@@ -275,7 +278,8 @@ int dcdbas_smi_request(struct smi_cmd *smi_cmd)
);
out:
- set_cpus_allowed_ptr(current, &old_mask);
+ set_cpus_allowed_ptr(current, old_mask);
+ free_cpumask_var(old_mask);
return ret;
}
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 3b77b67..c7b8a50 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -955,7 +955,7 @@ void ehca_poll_eqs(unsigned long data)
struct ehca_eq *eq = &shca->eq;
int max = 3;
volatile u64 q_ofs, q_ofs2;
- u64 flags;
+ unsigned long flags;
spin_lock_irqsave(&eq->spinlock, flags);
q_ofs = eq->ipz_queue.current_q_offset;
spin_unlock_irqrestore(&eq->spinlock, flags);
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c
index dcefe1f..61588bd 100644
--- a/drivers/infiniband/hw/mlx4/main.c
+++ b/drivers/infiniband/hw/mlx4/main.c
@@ -543,14 +543,21 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
{
static int mlx4_ib_version_printed;
struct mlx4_ib_dev *ibdev;
+ int num_ports = 0;
int i;
-
if (!mlx4_ib_version_printed) {
printk(KERN_INFO "%s", mlx4_ib_version);
++mlx4_ib_version_printed;
}
+ mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB)
+ num_ports++;
+
+ /* No point in registering a device with no ports... */
+ if (num_ports == 0)
+ return NULL;
+
ibdev = (struct mlx4_ib_dev *) ib_alloc_device(sizeof *ibdev);
if (!ibdev) {
dev_err(&dev->pdev->dev, "Device struct alloc failed\n");
@@ -574,9 +581,7 @@ static void *mlx4_ib_add(struct mlx4_dev *dev)
ibdev->ib_dev.owner = THIS_MODULE;
ibdev->ib_dev.node_type = RDMA_NODE_IB_CA;
ibdev->ib_dev.local_dma_lkey = dev->caps.reserved_lkey;
- ibdev->num_ports = 0;
- mlx4_foreach_port(i, dev, MLX4_PORT_TYPE_IB)
- ibdev->num_ports++;
+ ibdev->num_ports = num_ports;
ibdev->ib_dev.phys_port_cnt = ibdev->num_ports;
ibdev->ib_dev.num_comp_vectors = dev->caps.num_comp_vectors;
ibdev->ib_dev.dma_device = &dev->pdev->dev;
diff --git a/drivers/infiniband/hw/nes/nes_cm.c b/drivers/infiniband/hw/nes/nes_cm.c
index 6ba57e9..a01b448 100644
--- a/drivers/infiniband/hw/nes/nes_cm.c
+++ b/drivers/infiniband/hw/nes/nes_cm.c
@@ -778,12 +778,13 @@ static struct nes_cm_node *find_node(struct nes_cm_core *cm_core,
unsigned long flags;
struct list_head *hte;
struct nes_cm_node *cm_node;
+ __be32 tmp_addr = cpu_to_be32(loc_addr);
/* get a handle on the hte */
hte = &cm_core->connected_nodes;
nes_debug(NES_DBG_CM, "Searching for an owner node: %pI4:%x from core %p->%p\n",
- &loc_addr, loc_port, cm_core, hte);
+ &tmp_addr, loc_port, cm_core, hte);
/* walk list and find cm_node associated with this session ID */
spin_lock_irqsave(&cm_core->ht_lock, flags);
@@ -816,6 +817,7 @@ static struct nes_cm_listener *find_listener(struct nes_cm_core *cm_core,
{
unsigned long flags;
struct nes_cm_listener *listen_node;
+ __be32 tmp_addr = cpu_to_be32(dst_addr);
/* walk list and find cm_node associated with this session ID */
spin_lock_irqsave(&cm_core->listen_list_lock, flags);
@@ -833,7 +835,7 @@ static struct nes_cm_listener *find_listener(struct nes_cm_core *cm_core,
spin_unlock_irqrestore(&cm_core->listen_list_lock, flags);
nes_debug(NES_DBG_CM, "Unable to find listener for %pI4:%x\n",
- &dst_addr, dst_port);
+ &tmp_addr, dst_port);
/* no listener */
return NULL;
@@ -2059,6 +2061,7 @@ static int mini_cm_recv_pkt(struct nes_cm_core *cm_core,
struct tcphdr *tcph;
struct nes_cm_info nfo;
int skb_handled = 1;
+ __be32 tmp_daddr, tmp_saddr;
if (!skb)
return 0;
@@ -2074,8 +2077,11 @@ static int mini_cm_recv_pkt(struct nes_cm_core *cm_core,
nfo.rem_addr = ntohl(iph->saddr);
nfo.rem_port = ntohs(tcph->source);
+ tmp_daddr = cpu_to_be32(iph->daddr);
+ tmp_saddr = cpu_to_be32(iph->saddr);
+
nes_debug(NES_DBG_CM, "Received packet: dest=%pI4:0x%04X src=%pI4:0x%04X\n",
- &iph->daddr, tcph->dest, &iph->saddr, tcph->source);
+ &tmp_daddr, tcph->dest, &tmp_saddr, tcph->source);
do {
cm_node = find_node(cm_core,
diff --git a/drivers/infiniband/hw/nes/nes_utils.c b/drivers/infiniband/hw/nes/nes_utils.c
index aa9b734..6f3bc1b 100644
--- a/drivers/infiniband/hw/nes/nes_utils.c
+++ b/drivers/infiniband/hw/nes/nes_utils.c
@@ -655,6 +655,7 @@ int nes_arp_table(struct nes_device *nesdev, u32 ip_addr, u8 *mac_addr, u32 acti
struct nes_adapter *nesadapter = nesdev->nesadapter;
int arp_index;
int err = 0;
+ __be32 tmp_addr;
for (arp_index = 0; (u32) arp_index < nesadapter->arp_table_size; arp_index++) {
if (nesadapter->arp_table[arp_index].ip_addr == ip_addr)
@@ -682,8 +683,9 @@ int nes_arp_table(struct nes_device *nesdev, u32 ip_addr, u8 *mac_addr, u32 acti
/* DELETE or RESOLVE */
if (arp_index == nesadapter->arp_table_size) {
+ tmp_addr = cpu_to_be32(ip_addr);
nes_debug(NES_DBG_NETDEV, "MAC for %pI4 not in ARP table - cannot %s\n",
- &ip_addr, action == NES_ARP_RESOLVE ? "resolve" : "delete");
+ &tmp_addr, action == NES_ARP_RESOLVE ? "resolve" : "delete");
return -1;
}
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index 19e06bc..dce0443 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -711,26 +711,26 @@ static int ipoib_start_xmit(struct sk_buff *skb, struct net_device *dev)
neigh = *to_ipoib_neigh(skb->dst->neighbour);
- if (neigh->ah)
- if (unlikely((memcmp(&neigh->dgid.raw,
- skb->dst->neighbour->ha + 4,
- sizeof(union ib_gid))) ||
- (neigh->dev != dev))) {
- spin_lock_irqsave(&priv->lock, flags);
- /*
- * It's safe to call ipoib_put_ah() inside
- * priv->lock here, because we know that
- * path->ah will always hold one more reference,
- * so ipoib_put_ah() will never do more than
- * decrement the ref count.
- */
+ if (unlikely((memcmp(&neigh->dgid.raw,
+ skb->dst->neighbour->ha + 4,
+ sizeof(union ib_gid))) ||
+ (neigh->dev != dev))) {
+ spin_lock_irqsave(&priv->lock, flags);
+ /*
+ * It's safe to call ipoib_put_ah() inside
+ * priv->lock here, because we know that
+ * path->ah will always hold one more reference,
+ * so ipoib_put_ah() will never do more than
+ * decrement the ref count.
+ */
+ if (neigh->ah)
ipoib_put_ah(neigh->ah);
- list_del(&neigh->list);
- ipoib_neigh_free(dev, neigh);
- spin_unlock_irqrestore(&priv->lock, flags);
- ipoib_path_lookup(skb, dev);
- return NETDEV_TX_OK;
- }
+ list_del(&neigh->list);
+ ipoib_neigh_free(dev, neigh);
+ spin_unlock_irqrestore(&priv->lock, flags);
+ ipoib_path_lookup(skb, dev);
+ return NETDEV_TX_OK;
+ }
if (ipoib_cm_get(neigh)) {
if (ipoib_cm_up(neigh)) {
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index a2eb3b9..59d02e0 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -529,6 +529,9 @@ void ipoib_mcast_join_task(struct work_struct *work)
if (!priv->broadcast) {
struct ipoib_mcast *broadcast;
+ if (!test_bit(IPOIB_FLAG_ADMIN_UP, &priv->flags))
+ return;
+
broadcast = ipoib_mcast_alloc(dev, 1);
if (!broadcast) {
ipoib_warn(priv, "failed to allocate broadcast group\n");
diff --git a/drivers/infiniband/ulp/iser/Kconfig b/drivers/infiniband/ulp/iser/Kconfig
index 77dedba..b411c51 100644
--- a/drivers/infiniband/ulp/iser/Kconfig
+++ b/drivers/infiniband/ulp/iser/Kconfig
@@ -1,6 +1,6 @@
config INFINIBAND_ISER
tristate "iSCSI Extensions for RDMA (iSER)"
- depends on SCSI && INET
+ depends on SCSI && INET && INFINIBAND_ADDR_TRANS
select SCSI_ISCSI_ATTRS
---help---
Support for the iSCSI Extensions for RDMA (iSER) Protocol
diff --git a/drivers/input/misc/Kconfig b/drivers/input/misc/Kconfig
index 199055d..67e5553 100644
--- a/drivers/input/misc/Kconfig
+++ b/drivers/input/misc/Kconfig
@@ -220,4 +220,11 @@ config HP_SDC_RTC
Say Y here if you want to support the built-in real time clock
of the HP SDC controller.
+config INPUT_PCF50633_PMU
+ tristate "PCF50633 PMU events"
+ depends on MFD_PCF50633
+ help
+ Say Y to include support for delivering PMU events via input
+ layer on NXP PCF50633.
+
endif
diff --git a/drivers/input/misc/Makefile b/drivers/input/misc/Makefile
index d7db2ae..bb62e6e 100644
--- a/drivers/input/misc/Makefile
+++ b/drivers/input/misc/Makefile
@@ -21,3 +21,4 @@ obj-$(CONFIG_HP_SDC_RTC) += hp_sdc_rtc.o
obj-$(CONFIG_INPUT_UINPUT) += uinput.o
obj-$(CONFIG_INPUT_APANEL) += apanel.o
obj-$(CONFIG_INPUT_SGI_BTNS) += sgi_btns.o
+obj-$(CONFIG_INPUT_PCF50633_PMU) += pcf50633-input.o
diff --git a/drivers/input/misc/pcf50633-input.c b/drivers/input/misc/pcf50633-input.c
new file mode 100644
index 0000000..039dcb0
--- /dev/null
+++ b/drivers/input/misc/pcf50633-input.c
@@ -0,0 +1,132 @@
+/* NXP PCF50633 Input Driver
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * Author: Balaji Rao <balajirrao@openmoko.org>
+ * All rights reserved.
+ *
+ * Broken down from monstrous PCF50633 driver mainly by
+ * Harald Welte, Andy Green and Werner Almesberger
+ *
+ * This program is free software; you can redistribute 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/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/input.h>
+
+#include <linux/mfd/pcf50633/core.h>
+
+#define PCF50633_OOCSTAT_ONKEY 0x01
+#define PCF50633_REG_OOCSTAT 0x12
+#define PCF50633_REG_OOCMODE 0x10
+
+struct pcf50633_input {
+ struct pcf50633 *pcf;
+ struct input_dev *input_dev;
+};
+
+static void
+pcf50633_input_irq(int irq, void *data)
+{
+ struct pcf50633_input *input;
+ int onkey_released;
+
+ input = data;
+
+ /* We report only one event depending on the key press status */
+ onkey_released = pcf50633_reg_read(input->pcf, PCF50633_REG_OOCSTAT)
+ & PCF50633_OOCSTAT_ONKEY;
+
+ if (irq == PCF50633_IRQ_ONKEYF && !onkey_released)
+ input_report_key(input->input_dev, KEY_POWER, 1);
+ else if (irq == PCF50633_IRQ_ONKEYR && onkey_released)
+ input_report_key(input->input_dev, KEY_POWER, 0);
+
+ input_sync(input->input_dev);
+}
+
+static int __devinit pcf50633_input_probe(struct platform_device *pdev)
+{
+ struct pcf50633_input *input;
+ struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data;
+ struct input_dev *input_dev;
+ int ret;
+
+
+ input = kzalloc(sizeof(*input), GFP_KERNEL);
+ if (!input)
+ return -ENOMEM;
+
+ input_dev = input_allocate_device();
+ if (!input_dev) {
+ kfree(input);
+ return -ENOMEM;
+ }
+
+ platform_set_drvdata(pdev, input);
+ input->pcf = pdata->pcf;
+ input->input_dev = input_dev;
+
+ input_dev->name = "PCF50633 PMU events";
+ input_dev->id.bustype = BUS_I2C;
+ input_dev->evbit[0] = BIT(EV_KEY) | BIT(EV_PWR);
+ set_bit(KEY_POWER, input_dev->keybit);
+
+ ret = input_register_device(input_dev);
+ if (ret) {
+ input_free_device(input_dev);
+ kfree(input);
+ return ret;
+ }
+ pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYR,
+ pcf50633_input_irq, input);
+ pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ONKEYF,
+ pcf50633_input_irq, input);
+
+ return 0;
+}
+
+static int __devexit pcf50633_input_remove(struct platform_device *pdev)
+{
+ struct pcf50633_input *input = platform_get_drvdata(pdev);
+
+ pcf50633_free_irq(input->pcf, PCF50633_IRQ_ONKEYR);
+ pcf50633_free_irq(input->pcf, PCF50633_IRQ_ONKEYF);
+
+ input_unregister_device(input->input_dev);
+ kfree(input);
+
+ return 0;
+}
+
+static struct platform_driver pcf50633_input_driver = {
+ .driver = {
+ .name = "pcf50633-input",
+ },
+ .probe = pcf50633_input_probe,
+ .remove = __devexit_p(pcf50633_input_remove),
+};
+
+static int __init pcf50633_input_init(void)
+{
+ return platform_driver_register(&pcf50633_input_driver);
+}
+module_init(pcf50633_input_init);
+
+static void __exit pcf50633_input_exit(void)
+{
+ platform_driver_unregister(&pcf50633_input_driver);
+}
+module_exit(pcf50633_input_exit);
+
+MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
+MODULE_DESCRIPTION("PCF50633 input driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pcf50633-input");
diff --git a/drivers/isdn/hardware/mISDN/hfcmulti.c b/drivers/isdn/hardware/mISDN/hfcmulti.c
index 97f4708..595ba8e 100644
--- a/drivers/isdn/hardware/mISDN/hfcmulti.c
+++ b/drivers/isdn/hardware/mISDN/hfcmulti.c
@@ -3615,7 +3615,7 @@ hfcm_bctrl(struct mISDNchannel *ch, u_int cmd, void *arg)
static void
ph_state_change(struct dchannel *dch)
{
- struct hfc_multi *hc = dch->hw;
+ struct hfc_multi *hc;
int ch, i;
if (!dch) {
@@ -3623,6 +3623,7 @@ ph_state_change(struct dchannel *dch)
__func__);
return;
}
+ hc = dch->hw;
ch = dch->slot;
if (hc->type == 1) {
diff --git a/drivers/isdn/hardware/mISDN/hfcpci.c b/drivers/isdn/hardware/mISDN/hfcpci.c
index 917bf41..f0e14df 100644
--- a/drivers/isdn/hardware/mISDN/hfcpci.c
+++ b/drivers/isdn/hardware/mISDN/hfcpci.c
@@ -61,7 +61,7 @@ u32 hfc_jiffies;
MODULE_AUTHOR("Karsten Keil");
MODULE_LICENSE("GPL");
-module_param(debug, uint, 0);
+module_param(debug, uint, S_IRUGO | S_IWUSR);
module_param(poll, uint, S_IRUGO | S_IWUSR);
enum {
diff --git a/drivers/isdn/mISDN/dsp_cmx.c b/drivers/isdn/mISDN/dsp_cmx.c
index 0ac67bf..58c43e4 100644
--- a/drivers/isdn/mISDN/dsp_cmx.c
+++ b/drivers/isdn/mISDN/dsp_cmx.c
@@ -1579,7 +1579,7 @@ send_packet:
schedule_work(&dsp->workq);
}
-static u32 jittercount; /* counter for jitter check */;
+static u32 jittercount; /* counter for jitter check */
struct timer_list dsp_spl_tl;
u32 dsp_spl_jiffies; /* calculate the next time to fire */
static u16 dsp_count; /* last sample count */
@@ -1893,7 +1893,7 @@ dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb)
/* in case of hardware (echo) */
if (dsp->pcm_slot_tx >= 0)
return;
- if (dsp->echo)
+ if (dsp->echo) {
nskb = skb_clone(skb, GFP_ATOMIC);
if (nskb) {
hh = mISDN_HEAD_P(nskb);
@@ -1902,6 +1902,7 @@ dsp_cmx_hdlc(struct dsp *dsp, struct sk_buff *skb)
skb_queue_tail(&dsp->sendq, nskb);
schedule_work(&dsp->workq);
}
+ }
return;
}
/* in case of hardware conference */
diff --git a/drivers/isdn/mISDN/dsp_pipeline.c b/drivers/isdn/mISDN/dsp_pipeline.c
index bf999bd..18cf87c 100644
--- a/drivers/isdn/mISDN/dsp_pipeline.c
+++ b/drivers/isdn/mISDN/dsp_pipeline.c
@@ -110,8 +110,7 @@ int mISDN_dsp_element_register(struct mISDN_dsp_element *elem)
}
list_add_tail(&entry->list, &dsp_elements);
- for (i = 0; i < (sizeof(element_attributes)
- / sizeof(struct device_attribute)); ++i)
+ for (i = 0; i < ARRAY_SIZE(element_attributes); ++i) {
ret = device_create_file(&entry->dev,
&element_attributes[i]);
if (ret) {
@@ -119,6 +118,7 @@ int mISDN_dsp_element_register(struct mISDN_dsp_element *elem)
__func__);
goto err2;
}
+ }
#ifdef PIPELINE_DEBUG
printk(KERN_DEBUG "%s: %s registered\n", __func__, elem->name);
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index 416f9e7..06a2b0f 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -217,6 +217,29 @@ config MFD_WM8350_I2C
I2C as the control interface. Additional options must be
selected to enable support for the functionality of the chip.
+config MFD_PCF50633
+ tristate "Support for NXP PCF50633"
+ depends on I2C
+ help
+ Say yes here if you have NXP PCF50633 chip on your board.
+ This core driver provides register access and IRQ handling
+ facilities, and registers devices for the various functions
+ so that function-specific drivers can bind to them.
+
+config PCF50633_ADC
+ tristate "Support for NXP PCF50633 ADC"
+ depends on MFD_PCF50633
+ help
+ Say yes here if you want to include support for ADC in the
+ NXP PCF50633 chip.
+
+config PCF50633_GPIO
+ tristate "Support for NXP PCF50633 GPIO"
+ depends on MFD_PCF50633
+ help
+ Say yes here if you want to include support GPIO for pins on
+ the PCF50633 chip.
+
endmenu
menu "Multimedia Capabilities Port drivers"
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 0c9418b..3afb519 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -37,3 +37,7 @@ endif
obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o
obj-$(CONFIG_PMIC_DA903X) += da903x.o
+
+obj-$(CONFIG_MFD_PCF50633) += pcf50633-core.o
+obj-$(CONFIG_PCF50633_ADC) += pcf50633-adc.o
+obj-$(CONFIG_PCF50633_GPIO) += pcf50633-gpio.o \ No newline at end of file
diff --git a/drivers/mfd/dm355evm_msp.c b/drivers/mfd/dm355evm_msp.c
index 4214b3f..7ac12cb 100644
--- a/drivers/mfd/dm355evm_msp.c
+++ b/drivers/mfd/dm355evm_msp.c
@@ -107,6 +107,9 @@ static const u8 msp_gpios[] = {
MSP_GPIO(0, SWITCH1), MSP_GPIO(1, SWITCH1),
MSP_GPIO(2, SWITCH1), MSP_GPIO(3, SWITCH1),
MSP_GPIO(4, SWITCH1),
+ /* switches on MMC/SD sockets */
+ MSP_GPIO(1, SDMMC), MSP_GPIO(2, SDMMC), /* mmc0 WP, nCD */
+ MSP_GPIO(3, SDMMC), MSP_GPIO(4, SDMMC), /* mmc1 WP, nCD */
};
#define MSP_GPIO_REG(offset) (msp_gpios[(offset)] >> 3)
@@ -304,6 +307,13 @@ static int add_children(struct i2c_client *client)
gpio_export(gpio, false);
}
+ /* MMC/SD inputs -- right after the last config input */
+ if (client->dev.platform_data) {
+ void (*mmcsd_setup)(unsigned) = client->dev.platform_data;
+
+ mmcsd_setup(dm355evm_msp_gpio.base + 8 + 5);
+ }
+
/* RTC is a 32 bit counter, no alarm */
if (msp_has_rtc()) {
child = add_child(client, "rtc-dm355evm",
diff --git a/drivers/mfd/pcf50633-adc.c b/drivers/mfd/pcf50633-adc.c
new file mode 100644
index 0000000..c2d05be
--- /dev/null
+++ b/drivers/mfd/pcf50633-adc.c
@@ -0,0 +1,277 @@
+/* NXP PCF50633 ADC Driver
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * Author: Balaji Rao <balajirrao@openmoko.org>
+ * All rights reserved.
+ *
+ * Broken down from monstrous PCF50633 driver mainly by
+ * Harald Welte, Andy Green and Werner Almesberger
+ *
+ * This program is free software; you can redistribute 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: This driver does not yet support subtractive ADC mode, which means
+ * you can do only one measurement per read request.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/completion.h>
+
+#include <linux/mfd/pcf50633/core.h>
+#include <linux/mfd/pcf50633/adc.h>
+
+struct pcf50633_adc_request {
+ int mux;
+ int avg;
+ int result;
+ void (*callback)(struct pcf50633 *, void *, int);
+ void *callback_param;
+
+ /* Used in case of sync requests */
+ struct completion completion;
+
+};
+
+#define PCF50633_MAX_ADC_FIFO_DEPTH 8
+
+struct pcf50633_adc {
+ struct pcf50633 *pcf;
+
+ /* Private stuff */
+ struct pcf50633_adc_request *queue[PCF50633_MAX_ADC_FIFO_DEPTH];
+ int queue_head;
+ int queue_tail;
+ struct mutex queue_mutex;
+};
+
+static inline struct pcf50633_adc *__to_adc(struct pcf50633 *pcf)
+{
+ return platform_get_drvdata(pcf->adc_pdev);
+}
+
+static void adc_setup(struct pcf50633 *pcf, int channel, int avg)
+{
+ channel &= PCF50633_ADCC1_ADCMUX_MASK;
+
+ /* kill ratiometric, but enable ACCSW biasing */
+ pcf50633_reg_write(pcf, PCF50633_REG_ADCC2, 0x00);
+ pcf50633_reg_write(pcf, PCF50633_REG_ADCC3, 0x01);
+
+ /* start ADC conversion on selected channel */
+ pcf50633_reg_write(pcf, PCF50633_REG_ADCC1, channel | avg |
+ PCF50633_ADCC1_ADCSTART | PCF50633_ADCC1_RES_10BIT);
+}
+
+static void trigger_next_adc_job_if_any(struct pcf50633 *pcf)
+{
+ struct pcf50633_adc *adc = __to_adc(pcf);
+ int head;
+
+ mutex_lock(&adc->queue_mutex);
+
+ head = adc->queue_head;
+
+ if (!adc->queue[head]) {
+ mutex_unlock(&adc->queue_mutex);
+ return;
+ }
+ mutex_unlock(&adc->queue_mutex);
+
+ adc_setup(pcf, adc->queue[head]->mux, adc->queue[head]->avg);
+}
+
+static int
+adc_enqueue_request(struct pcf50633 *pcf, struct pcf50633_adc_request *req)
+{
+ struct pcf50633_adc *adc = __to_adc(pcf);
+ int head, tail;
+
+ mutex_lock(&adc->queue_mutex);
+
+ head = adc->queue_head;
+ tail = adc->queue_tail;
+
+ if (adc->queue[tail]) {
+ mutex_unlock(&adc->queue_mutex);
+ return -EBUSY;
+ }
+
+ adc->queue[tail] = req;
+ adc->queue_tail = (tail + 1) & (PCF50633_MAX_ADC_FIFO_DEPTH - 1);
+
+ mutex_unlock(&adc->queue_mutex);
+
+ trigger_next_adc_job_if_any(pcf);
+
+ return 0;
+}
+
+static void
+pcf50633_adc_sync_read_callback(struct pcf50633 *pcf, void *param, int result)
+{
+ struct pcf50633_adc_request *req = param;
+
+ req->result = result;
+ complete(&req->completion);
+}
+
+int pcf50633_adc_sync_read(struct pcf50633 *pcf, int mux, int avg)
+{
+ struct pcf50633_adc_request *req;
+
+ /* req is freed when the result is ready, in interrupt handler */
+ req = kzalloc(sizeof(*req), GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+
+ req->mux = mux;
+ req->avg = avg;
+ req->callback = pcf50633_adc_sync_read_callback;
+ req->callback_param = req;
+
+ init_completion(&req->completion);
+ adc_enqueue_request(pcf, req);
+ wait_for_completion(&req->completion);
+
+ return req->result;
+}
+EXPORT_SYMBOL_GPL(pcf50633_adc_sync_read);
+
+int pcf50633_adc_async_read(struct pcf50633 *pcf, int mux, int avg,
+ void (*callback)(struct pcf50633 *, void *, int),
+ void *callback_param)
+{
+ struct pcf50633_adc_request *req;
+
+ /* req is freed when the result is ready, in interrupt handler */
+ req = kmalloc(sizeof(*req), GFP_KERNEL);
+ if (!req)
+ return -ENOMEM;
+
+ req->mux = mux;
+ req->avg = avg;
+ req->callback = callback;
+ req->callback_param = callback_param;
+
+ adc_enqueue_request(pcf, req);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pcf50633_adc_async_read);
+
+static int adc_result(struct pcf50633 *pcf)
+{
+ u8 adcs1, adcs3;
+ u16 result;
+
+ adcs1 = pcf50633_reg_read(pcf, PCF50633_REG_ADCS1);
+ adcs3 = pcf50633_reg_read(pcf, PCF50633_REG_ADCS3);
+ result = (adcs1 << 2) | (adcs3 & PCF50633_ADCS3_ADCDAT1L_MASK);
+
+ dev_dbg(pcf->dev, "adc result = %d\n", result);
+
+ return result;
+}
+
+static void pcf50633_adc_irq(int irq, void *data)
+{
+ struct pcf50633_adc *adc = data;
+ struct pcf50633 *pcf = adc->pcf;
+ struct pcf50633_adc_request *req;
+ int head;
+
+ mutex_lock(&adc->queue_mutex);
+ head = adc->queue_head;
+
+ req = adc->queue[head];
+ if (WARN_ON(!req)) {
+ dev_err(pcf->dev, "pcf50633-adc irq: ADC queue empty!\n");
+ mutex_unlock(&adc->queue_mutex);
+ return;
+ }
+ adc->queue[head] = NULL;
+ adc->queue_head = (head + 1) &
+ (PCF50633_MAX_ADC_FIFO_DEPTH - 1);
+
+ mutex_unlock(&adc->queue_mutex);
+
+ req->callback(pcf, req->callback_param, adc_result(pcf));
+ kfree(req);
+
+ trigger_next_adc_job_if_any(pcf);
+}
+
+static int __devinit pcf50633_adc_probe(struct platform_device *pdev)
+{
+ struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data;
+ struct pcf50633_adc *adc;
+
+ adc = kzalloc(sizeof(*adc), GFP_KERNEL);
+ if (!adc)
+ return -ENOMEM;
+
+ adc->pcf = pdata->pcf;
+ platform_set_drvdata(pdev, adc);
+
+ pcf50633_register_irq(pdata->pcf, PCF50633_IRQ_ADCRDY,
+ pcf50633_adc_irq, adc);
+
+ mutex_init(&adc->queue_mutex);
+
+ return 0;
+}
+
+static int __devexit pcf50633_adc_remove(struct platform_device *pdev)
+{
+ struct pcf50633_adc *adc = platform_get_drvdata(pdev);
+ int i, head;
+
+ pcf50633_free_irq(adc->pcf, PCF50633_IRQ_ADCRDY);
+
+ mutex_lock(&adc->queue_mutex);
+ head = adc->queue_head;
+
+ if (WARN_ON(adc->queue[head]))
+ dev_err(adc->pcf->dev,
+ "adc driver removed with request pending\n");
+
+ for (i = 0; i < PCF50633_MAX_ADC_FIFO_DEPTH; i++)
+ kfree(adc->queue[i]);
+
+ mutex_unlock(&adc->queue_mutex);
+ kfree(adc);
+
+ return 0;
+}
+
+static struct platform_driver pcf50633_adc_driver = {
+ .driver = {
+ .name = "pcf50633-adc",
+ },
+ .probe = pcf50633_adc_probe,
+ .remove = __devexit_p(pcf50633_adc_remove),
+};
+
+static int __init pcf50633_adc_init(void)
+{
+ return platform_driver_register(&pcf50633_adc_driver);
+}
+module_init(pcf50633_adc_init);
+
+static void __exit pcf50633_adc_exit(void)
+{
+ platform_driver_unregister(&pcf50633_adc_driver);
+}
+module_exit(pcf50633_adc_exit);
+
+MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
+MODULE_DESCRIPTION("PCF50633 adc driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pcf50633-adc");
+
diff --git a/drivers/mfd/pcf50633-core.c b/drivers/mfd/pcf50633-core.c
new file mode 100644
index 0000000..24508e2
--- /dev/null
+++ b/drivers/mfd/pcf50633-core.c
@@ -0,0 +1,710 @@
+/* NXP PCF50633 Power Management Unit (PMU) driver
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * Author: Harald Welte <laforge@openmoko.org>
+ * Balaji Rao <balajirrao@openmoko.org>
+ * 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.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/sysfs.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/interrupt.h>
+#include <linux/workqueue.h>
+#include <linux/platform_device.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+
+#include <linux/mfd/pcf50633/core.h>
+
+/* Two MBCS registers used during cold start */
+#define PCF50633_REG_MBCS1 0x4b
+#define PCF50633_REG_MBCS2 0x4c
+#define PCF50633_MBCS1_USBPRES 0x01
+#define PCF50633_MBCS1_ADAPTPRES 0x01
+
+static int __pcf50633_read(struct pcf50633 *pcf, u8 reg, int num, u8 *data)
+{
+ int ret;
+
+ ret = i2c_smbus_read_i2c_block_data(pcf->i2c_client, reg,
+ num, data);
+ if (ret < 0)
+ dev_err(pcf->dev, "Error reading %d regs at %d\n", num, reg);
+
+ return ret;
+}
+
+static int __pcf50633_write(struct pcf50633 *pcf, u8 reg, int num, u8 *data)
+{
+ int ret;
+
+ ret = i2c_smbus_write_i2c_block_data(pcf->i2c_client, reg,
+ num, data);
+ if (ret < 0)
+ dev_err(pcf->dev, "Error writing %d regs at %d\n", num, reg);
+
+ return ret;
+
+}
+
+/* Read a block of upto 32 regs */
+int pcf50633_read_block(struct pcf50633 *pcf, u8 reg,
+ int nr_regs, u8 *data)
+{
+ int ret;
+
+ mutex_lock(&pcf->lock);
+ ret = __pcf50633_read(pcf, reg, nr_regs, data);
+ mutex_unlock(&pcf->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pcf50633_read_block);
+
+/* Write a block of upto 32 regs */
+int pcf50633_write_block(struct pcf50633 *pcf , u8 reg,
+ int nr_regs, u8 *data)
+{
+ int ret;
+
+ mutex_lock(&pcf->lock);
+ ret = __pcf50633_write(pcf, reg, nr_regs, data);
+ mutex_unlock(&pcf->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pcf50633_write_block);
+
+u8 pcf50633_reg_read(struct pcf50633 *pcf, u8 reg)
+{
+ u8 val;
+
+ mutex_lock(&pcf->lock);
+ __pcf50633_read(pcf, reg, 1, &val);
+ mutex_unlock(&pcf->lock);
+
+ return val;
+}
+EXPORT_SYMBOL_GPL(pcf50633_reg_read);
+
+int pcf50633_reg_write(struct pcf50633 *pcf, u8 reg, u8 val)
+{
+ int ret;
+
+ mutex_lock(&pcf->lock);
+ ret = __pcf50633_write(pcf, reg, 1, &val);
+ mutex_unlock(&pcf->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pcf50633_reg_write);
+
+int pcf50633_reg_set_bit_mask(struct pcf50633 *pcf, u8 reg, u8 mask, u8 val)
+{
+ int ret;
+ u8 tmp;
+
+ val &= mask;
+
+ mutex_lock(&pcf->lock);
+ ret = __pcf50633_read(pcf, reg, 1, &tmp);
+ if (ret < 0)
+ goto out;
+
+ tmp &= ~mask;
+ tmp |= val;
+ ret = __pcf50633_write(pcf, reg, 1, &tmp);
+
+out:
+ mutex_unlock(&pcf->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pcf50633_reg_set_bit_mask);
+
+int pcf50633_reg_clear_bits(struct pcf50633 *pcf, u8 reg, u8 val)
+{
+ int ret;
+ u8 tmp;
+
+ mutex_lock(&pcf->lock);
+ ret = __pcf50633_read(pcf, reg, 1, &tmp);
+ if (ret < 0)
+ goto out;
+
+ tmp &= ~val;
+ ret = __pcf50633_write(pcf, reg, 1, &tmp);
+
+out:
+ mutex_unlock(&pcf->lock);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pcf50633_reg_clear_bits);
+
+/* sysfs attributes */
+static ssize_t show_dump_regs(struct device *dev, struct device_attribute *attr,
+ char *buf)
+{
+ struct pcf50633 *pcf = dev_get_drvdata(dev);
+ u8 dump[16];
+ int n, n1, idx = 0;
+ char *buf1 = buf;
+ static u8 address_no_read[] = { /* must be ascending */
+ PCF50633_REG_INT1,
+ PCF50633_REG_INT2,
+ PCF50633_REG_INT3,
+ PCF50633_REG_INT4,
+ PCF50633_REG_INT5,
+ 0 /* terminator */
+ };
+
+ for (n = 0; n < 256; n += sizeof(dump)) {
+ for (n1 = 0; n1 < sizeof(dump); n1++)
+ if (n == address_no_read[idx]) {
+ idx++;
+ dump[n1] = 0x00;
+ } else
+ dump[n1] = pcf50633_reg_read(pcf, n + n1);
+
+ hex_dump_to_buffer(dump, sizeof(dump), 16, 1, buf1, 128, 0);
+ buf1 += strlen(buf1);
+ *buf1++ = '\n';
+ *buf1 = '\0';
+ }
+
+ return buf1 - buf;
+}
+static DEVICE_ATTR(dump_regs, 0400, show_dump_regs, NULL);
+
+static ssize_t show_resume_reason(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct pcf50633 *pcf = dev_get_drvdata(dev);
+ int n;
+
+ n = sprintf(buf, "%02x%02x%02x%02x%02x\n",
+ pcf->resume_reason[0],
+ pcf->resume_reason[1],
+ pcf->resume_reason[2],
+ pcf->resume_reason[3],
+ pcf->resume_reason[4]);
+
+ return n;
+}
+static DEVICE_ATTR(resume_reason, 0400, show_resume_reason, NULL);
+
+static struct attribute *pcf_sysfs_entries[] = {
+ &dev_attr_dump_regs.attr,
+ &dev_attr_resume_reason.attr,
+ NULL,
+};
+
+static struct attribute_group pcf_attr_group = {
+ .name = NULL, /* put in device directory */
+ .attrs = pcf_sysfs_entries,
+};
+
+int pcf50633_register_irq(struct pcf50633 *pcf, int irq,
+ void (*handler) (int, void *), void *data)
+{
+ if (irq < 0 || irq > PCF50633_NUM_IRQ || !handler)
+ return -EINVAL;
+
+ if (WARN_ON(pcf->irq_handler[irq].handler))
+ return -EBUSY;
+
+ mutex_lock(&pcf->lock);
+ pcf->irq_handler[irq].handler = handler;
+ pcf->irq_handler[irq].data = data;
+ mutex_unlock(&pcf->lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pcf50633_register_irq);
+
+int pcf50633_free_irq(struct pcf50633 *pcf, int irq)
+{
+ if (irq < 0 || irq > PCF50633_NUM_IRQ)
+ return -EINVAL;
+
+ mutex_lock(&pcf->lock);
+ pcf->irq_handler[irq].handler = NULL;
+ mutex_unlock(&pcf->lock);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(pcf50633_free_irq);
+
+static int __pcf50633_irq_mask_set(struct pcf50633 *pcf, int irq, u8 mask)
+{
+ u8 reg, bits, tmp;
+ int ret = 0, idx;
+
+ idx = irq >> 3;
+ reg = PCF50633_REG_INT1M + idx;
+ bits = 1 << (irq & 0x07);
+
+ mutex_lock(&pcf->lock);
+
+ if (mask) {
+ ret = __pcf50633_read(pcf, reg, 1, &tmp);
+ if (ret < 0)
+ goto out;
+
+ tmp |= bits;
+
+ ret = __pcf50633_write(pcf, reg, 1, &tmp);
+ if (ret < 0)
+ goto out;
+
+ pcf->mask_regs[idx] &= ~bits;
+ pcf->mask_regs[idx] |= bits;
+ } else {
+ ret = __pcf50633_read(pcf, reg, 1, &tmp);
+ if (ret < 0)
+ goto out;
+
+ tmp &= ~bits;
+
+ ret = __pcf50633_write(pcf, reg, 1, &tmp);
+ if (ret < 0)
+ goto out;
+
+ pcf->mask_regs[idx] &= ~bits;
+ }
+out:
+ mutex_unlock(&pcf->lock);
+
+ return ret;
+}
+
+int pcf50633_irq_mask(struct pcf50633 *pcf, int irq)
+{
+ dev_info(pcf->dev, "Masking IRQ %d\n", irq);
+
+ return __pcf50633_irq_mask_set(pcf, irq, 1);
+}
+EXPORT_SYMBOL_GPL(pcf50633_irq_mask);
+
+int pcf50633_irq_unmask(struct pcf50633 *pcf, int irq)
+{
+ dev_info(pcf->dev, "Unmasking IRQ %d\n", irq);
+
+ return __pcf50633_irq_mask_set(pcf, irq, 0);
+}
+EXPORT_SYMBOL_GPL(pcf50633_irq_unmask);
+
+int pcf50633_irq_mask_get(struct pcf50633 *pcf, int irq)
+{
+ u8 reg, bits;
+
+ reg = irq >> 3;
+ bits = 1 << (irq & 0x07);
+
+ return pcf->mask_regs[reg] & bits;
+}
+EXPORT_SYMBOL_GPL(pcf50633_irq_mask_get);
+
+static void pcf50633_irq_call_handler(struct pcf50633 *pcf, int irq)
+{
+ if (pcf->irq_handler[irq].handler)
+ pcf->irq_handler[irq].handler(irq, pcf->irq_handler[irq].data);
+}
+
+/* Maximum amount of time ONKEY is held before emergency action is taken */
+#define PCF50633_ONKEY1S_TIMEOUT 8
+
+static void pcf50633_irq_worker(struct work_struct *work)
+{
+ struct pcf50633 *pcf;
+ int ret, i, j;
+ u8 pcf_int[5], chgstat;
+
+ pcf = container_of(work, struct pcf50633, irq_work);
+
+ /* Read the 5 INT regs in one transaction */
+ ret = pcf50633_read_block(pcf, PCF50633_REG_INT1,
+ ARRAY_SIZE(pcf_int), pcf_int);
+ if (ret != ARRAY_SIZE(pcf_int)) {
+ dev_err(pcf->dev, "Error reading INT registers\n");
+
+ /*
+ * If this doesn't ACK the interrupt to the chip, we'll be
+ * called once again as we're level triggered.
+ */
+ goto out;
+ }
+
+ /* We immediately read the usb and adapter status. We thus make sure
+ * only of USBINS/USBREM IRQ handlers are called */
+ if (pcf_int[0] & (PCF50633_INT1_USBINS | PCF50633_INT1_USBREM)) {
+ chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
+ if (chgstat & (0x3 << 4))
+ pcf_int[0] &= ~(1 << PCF50633_INT1_USBREM);
+ else
+ pcf_int[0] &= ~(1 << PCF50633_INT1_USBINS);
+ }
+
+ /* Make sure only one of ADPINS or ADPREM is set */
+ if (pcf_int[0] & (PCF50633_INT1_ADPINS | PCF50633_INT1_ADPREM)) {
+ chgstat = pcf50633_reg_read(pcf, PCF50633_REG_MBCS2);
+ if (chgstat & (0x3 << 4))
+ pcf_int[0] &= ~(1 << PCF50633_INT1_ADPREM);
+ else
+ pcf_int[0] &= ~(1 << PCF50633_INT1_ADPINS);
+ }
+
+ dev_dbg(pcf->dev, "INT1=0x%02x INT2=0x%02x INT3=0x%02x "
+ "INT4=0x%02x INT5=0x%02x\n", pcf_int[0],
+ pcf_int[1], pcf_int[2], pcf_int[3], pcf_int[4]);
+
+ /* Some revisions of the chip don't have a 8s standby mode on
+ * ONKEY1S press. We try to manually do it in such cases. */
+ if ((pcf_int[0] & PCF50633_INT1_SECOND) && pcf->onkey1s_held) {
+ dev_info(pcf->dev, "ONKEY1S held for %d secs\n",
+ pcf->onkey1s_held);
+ if (pcf->onkey1s_held++ == PCF50633_ONKEY1S_TIMEOUT)
+ if (pcf->pdata->force_shutdown)
+ pcf->pdata->force_shutdown(pcf);
+ }
+
+ if (pcf_int[2] & PCF50633_INT3_ONKEY1S) {
+ dev_info(pcf->dev, "ONKEY1S held\n");
+ pcf->onkey1s_held = 1 ;
+
+ /* Unmask IRQ_SECOND */
+ pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT1M,
+ PCF50633_INT1_SECOND);
+
+ /* Unmask IRQ_ONKEYR */
+ pcf50633_reg_clear_bits(pcf, PCF50633_REG_INT2M,
+ PCF50633_INT2_ONKEYR);
+ }
+
+ if ((pcf_int[1] & PCF50633_INT2_ONKEYR) && pcf->onkey1s_held) {
+ pcf->onkey1s_held = 0;
+
+ /* Mask SECOND and ONKEYR interrupts */
+ if (pcf->mask_regs[0] & PCF50633_INT1_SECOND)
+ pcf50633_reg_set_bit_mask(pcf,
+ PCF50633_REG_INT1M,
+ PCF50633_INT1_SECOND,
+ PCF50633_INT1_SECOND);
+
+ if (pcf->mask_regs[1] & PCF50633_INT2_ONKEYR)
+ pcf50633_reg_set_bit_mask(pcf,
+ PCF50633_REG_INT2M,
+ PCF50633_INT2_ONKEYR,
+ PCF50633_INT2_ONKEYR);
+ }
+
+ /* Have we just resumed ? */
+ if (pcf->is_suspended) {
+ pcf->is_suspended = 0;
+
+ /* Set the resume reason filtering out non resumers */
+ for (i = 0; i < ARRAY_SIZE(pcf_int); i++)
+ pcf->resume_reason[i] = pcf_int[i] &
+ pcf->pdata->resumers[i];
+
+ /* Make sure we don't pass on any ONKEY events to
+ * userspace now */
+ pcf_int[1] &= ~(PCF50633_INT2_ONKEYR | PCF50633_INT2_ONKEYF);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(pcf_int); i++) {
+ /* Unset masked interrupts */
+ pcf_int[i] &= ~pcf->mask_regs[i];
+
+ for (j = 0; j < 8 ; j++)
+ if (pcf_int[i] & (1 << j))
+ pcf50633_irq_call_handler(pcf, (i * 8) + j);
+ }
+
+out:
+ put_device(pcf->dev);
+ enable_irq(pcf->irq);
+}
+
+static irqreturn_t pcf50633_irq(int irq, void *data)
+{
+ struct pcf50633 *pcf = data;
+
+ dev_dbg(pcf->dev, "pcf50633_irq\n");
+
+ get_device(pcf->dev);
+ disable_irq(pcf->irq);
+ schedule_work(&pcf->irq_work);
+
+ return IRQ_HANDLED;
+}
+
+static void
+pcf50633_client_dev_register(struct pcf50633 *pcf, const char *name,
+ struct platform_device **pdev)
+{
+ struct pcf50633_subdev_pdata *subdev_pdata;
+ int ret;
+
+ *pdev = platform_device_alloc(name, -1);
+ if (!*pdev) {
+ dev_err(pcf->dev, "Falied to allocate %s\n", name);
+ return;
+ }
+
+ subdev_pdata = kmalloc(sizeof(*subdev_pdata), GFP_KERNEL);
+ if (!subdev_pdata) {
+ dev_err(pcf->dev, "Error allocating subdev pdata\n");
+ platform_device_put(*pdev);
+ }
+
+ subdev_pdata->pcf = pcf;
+ platform_device_add_data(*pdev, subdev_pdata, sizeof(*subdev_pdata));
+
+ (*pdev)->dev.parent = pcf->dev;
+
+ ret = platform_device_add(*pdev);
+ if (ret) {
+ dev_err(pcf->dev, "Failed to register %s: %d\n", name, ret);
+ platform_device_put(*pdev);
+ *pdev = NULL;
+ }
+}
+
+#ifdef CONFIG_PM
+static int pcf50633_suspend(struct device *dev, pm_message_t state)
+{
+ struct pcf50633 *pcf;
+ int ret = 0, i;
+ u8 res[5];
+
+ pcf = dev_get_drvdata(dev);
+
+ /* Make sure our interrupt handlers are not called
+ * henceforth */
+ disable_irq(pcf->irq);
+
+ /* Make sure that any running IRQ worker has quit */
+ cancel_work_sync(&pcf->irq_work);
+
+ /* Save the masks */
+ ret = pcf50633_read_block(pcf, PCF50633_REG_INT1M,
+ ARRAY_SIZE(pcf->suspend_irq_masks),
+ pcf->suspend_irq_masks);
+ if (ret < 0) {
+ dev_err(pcf->dev, "error saving irq masks\n");
+ goto out;
+ }
+
+ /* Write wakeup irq masks */
+ for (i = 0; i < ARRAY_SIZE(res); i++)
+ res[i] = ~pcf->pdata->resumers[i];
+
+ ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
+ ARRAY_SIZE(res), &res[0]);
+ if (ret < 0) {
+ dev_err(pcf->dev, "error writing wakeup irq masks\n");
+ goto out;
+ }
+
+ pcf->is_suspended = 1;
+
+out:
+ return ret;
+}
+
+static int pcf50633_resume(struct device *dev)
+{
+ struct pcf50633 *pcf;
+ int ret;
+
+ pcf = dev_get_drvdata(dev);
+
+ /* Write the saved mask registers */
+ ret = pcf50633_write_block(pcf, PCF50633_REG_INT1M,
+ ARRAY_SIZE(pcf->suspend_irq_masks),
+ pcf->suspend_irq_masks);
+ if (ret < 0)
+ dev_err(pcf->dev, "Error restoring saved suspend masks\n");
+
+ /* Restore regulators' state */
+
+
+ get_device(pcf->dev);
+
+ /*
+ * Clear any pending interrupts and set resume reason if any.
+ * This will leave with enable_irq()
+ */
+ pcf50633_irq_worker(&pcf->irq_work);
+
+ return 0;
+}
+#else
+#define pcf50633_suspend NULL
+#define pcf50633_resume NULL
+#endif
+
+static int __devinit pcf50633_probe(struct i2c_client *client,
+ const struct i2c_device_id *ids)
+{
+ struct pcf50633 *pcf;
+ struct pcf50633_platform_data *pdata = client->dev.platform_data;
+ int i, ret = 0;
+ int version, variant;
+
+ pcf = kzalloc(sizeof(*pcf), GFP_KERNEL);
+ if (!pcf)
+ return -ENOMEM;
+
+ pcf->pdata = pdata;
+
+ mutex_init(&pcf->lock);
+
+ i2c_set_clientdata(client, pcf);
+ pcf->dev = &client->dev;
+ pcf->i2c_client = client;
+ pcf->irq = client->irq;
+
+ INIT_WORK(&pcf->irq_work, pcf50633_irq_worker);
+
+ version = pcf50633_reg_read(pcf, 0);
+ variant = pcf50633_reg_read(pcf, 1);
+ if (version < 0 || variant < 0) {
+ dev_err(pcf->dev, "Unable to probe pcf50633\n");
+ ret = -ENODEV;
+ goto err;
+ }
+
+ dev_info(pcf->dev, "Probed device version %d variant %d\n",
+ version, variant);
+
+ /* Enable all interrupts except RTC SECOND */
+ pcf->mask_regs[0] = 0x80;
+ pcf50633_reg_write(pcf, PCF50633_REG_INT1M, pcf->mask_regs[0]);
+ pcf50633_reg_write(pcf, PCF50633_REG_INT2M, 0x00);
+ pcf50633_reg_write(pcf, PCF50633_REG_INT3M, 0x00);
+ pcf50633_reg_write(pcf, PCF50633_REG_INT4M, 0x00);
+ pcf50633_reg_write(pcf, PCF50633_REG_INT5M, 0x00);
+
+ /* Create sub devices */
+ pcf50633_client_dev_register(pcf, "pcf50633-input",
+ &pcf->input_pdev);
+ pcf50633_client_dev_register(pcf, "pcf50633-rtc",
+ &pcf->rtc_pdev);
+ pcf50633_client_dev_register(pcf, "pcf50633-mbc",
+ &pcf->mbc_pdev);
+ pcf50633_client_dev_register(pcf, "pcf50633-adc",
+ &pcf->adc_pdev);
+
+ for (i = 0; i < PCF50633_NUM_REGULATORS; i++) {
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc("pcf50633-regltr", i);
+ if (!pdev) {
+ dev_err(pcf->dev, "Cannot create regulator\n");
+ continue;
+ }
+
+ pdev->dev.parent = pcf->dev;
+ pdev->dev.platform_data = &pdata->reg_init_data[i];
+ pdev->dev.driver_data = pcf;
+ pcf->regulator_pdev[i] = pdev;
+
+ platform_device_add(pdev);
+ }
+
+ if (client->irq) {
+ set_irq_handler(client->irq, handle_level_irq);
+ ret = request_irq(client->irq, pcf50633_irq,
+ IRQF_TRIGGER_LOW, "pcf50633", pcf);
+
+ if (ret) {
+ dev_err(pcf->dev, "Failed to request IRQ %d\n", ret);
+ goto err;
+ }
+ } else {
+ dev_err(pcf->dev, "No IRQ configured\n");
+ goto err;
+ }
+
+ if (enable_irq_wake(client->irq) < 0)
+ dev_err(pcf->dev, "IRQ %u cannot be enabled as wake-up source"
+ "in this hardware revision", client->irq);
+
+ ret = sysfs_create_group(&client->dev.kobj, &pcf_attr_group);
+ if (ret)
+ dev_err(pcf->dev, "error creating sysfs entries\n");
+
+ if (pdata->probe_done)
+ pdata->probe_done(pcf);
+
+ return 0;
+
+err:
+ kfree(pcf);
+ return ret;
+}
+
+static int __devexit pcf50633_remove(struct i2c_client *client)
+{
+ struct pcf50633 *pcf = i2c_get_clientdata(client);
+ int i;
+
+ free_irq(pcf->irq, pcf);
+
+ platform_device_unregister(pcf->input_pdev);
+ platform_device_unregister(pcf->rtc_pdev);
+ platform_device_unregister(pcf->mbc_pdev);
+ platform_device_unregister(pcf->adc_pdev);
+
+ for (i = 0; i < PCF50633_NUM_REGULATORS; i++)
+ platform_device_unregister(pcf->regulator_pdev[i]);
+
+ kfree(pcf);
+
+ return 0;
+}
+
+static struct i2c_device_id pcf50633_id_table[] = {
+ {"pcf50633", 0x73},
+};
+
+static struct i2c_driver pcf50633_driver = {
+ .driver = {
+ .name = "pcf50633",
+ .suspend = pcf50633_suspend,
+ .resume = pcf50633_resume,
+ },
+ .id_table = pcf50633_id_table,
+ .probe = pcf50633_probe,
+ .remove = __devexit_p(pcf50633_remove),
+};
+
+static int __init pcf50633_init(void)
+{
+ return i2c_add_driver(&pcf50633_driver);
+}
+
+static void __exit pcf50633_exit(void)
+{
+ i2c_del_driver(&pcf50633_driver);
+}
+
+MODULE_DESCRIPTION("I2C chip driver for NXP PCF50633 PMU");
+MODULE_AUTHOR("Harald Welte <laforge@openmoko.org>");
+MODULE_LICENSE("GPL");
+
+module_init(pcf50633_init);
+module_exit(pcf50633_exit);
diff --git a/drivers/mfd/pcf50633-gpio.c b/drivers/mfd/pcf50633-gpio.c
new file mode 100644
index 0000000..2fa2eca
--- /dev/null
+++ b/drivers/mfd/pcf50633-gpio.c
@@ -0,0 +1,118 @@
+/* NXP PCF50633 GPIO Driver
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * Author: Balaji Rao <balajirrao@openmoko.org>
+ * All rights reserved.
+ *
+ * Broken down from monstrous PCF50633 driver mainly by
+ * Harald Welte, Andy Green and Werner Almesberger
+ *
+ * This program is free software; you can redistribute 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/mfd/pcf50633/core.h>
+#include <linux/mfd/pcf50633/gpio.h>
+
+enum pcf50633_regulator_id {
+ PCF50633_REGULATOR_AUTO,
+ PCF50633_REGULATOR_DOWN1,
+ PCF50633_REGULATOR_DOWN2,
+ PCF50633_REGULATOR_LDO1,
+ PCF50633_REGULATOR_LDO2,
+ PCF50633_REGULATOR_LDO3,
+ PCF50633_REGULATOR_LDO4,
+ PCF50633_REGULATOR_LDO5,
+ PCF50633_REGULATOR_LDO6,
+ PCF50633_REGULATOR_HCLDO,
+ PCF50633_REGULATOR_MEMLDO,
+};
+
+#define PCF50633_REG_AUTOOUT 0x1a
+#define PCF50633_REG_DOWN1OUT 0x1e
+#define PCF50633_REG_DOWN2OUT 0x22
+#define PCF50633_REG_MEMLDOOUT 0x26
+#define PCF50633_REG_LDO1OUT 0x2d
+#define PCF50633_REG_LDO2OUT 0x2f
+#define PCF50633_REG_LDO3OUT 0x31
+#define PCF50633_REG_LDO4OUT 0x33
+#define PCF50633_REG_LDO5OUT 0x35
+#define PCF50633_REG_LDO6OUT 0x37
+#define PCF50633_REG_HCLDOOUT 0x39
+
+static const u8 pcf50633_regulator_registers[PCF50633_NUM_REGULATORS] = {
+ [PCF50633_REGULATOR_AUTO] = PCF50633_REG_AUTOOUT,
+ [PCF50633_REGULATOR_DOWN1] = PCF50633_REG_DOWN1OUT,
+ [PCF50633_REGULATOR_DOWN2] = PCF50633_REG_DOWN2OUT,
+ [PCF50633_REGULATOR_MEMLDO] = PCF50633_REG_MEMLDOOUT,
+ [PCF50633_REGULATOR_LDO1] = PCF50633_REG_LDO1OUT,
+ [PCF50633_REGULATOR_LDO2] = PCF50633_REG_LDO2OUT,
+ [PCF50633_REGULATOR_LDO3] = PCF50633_REG_LDO3OUT,
+ [PCF50633_REGULATOR_LDO4] = PCF50633_REG_LDO4OUT,
+ [PCF50633_REGULATOR_LDO5] = PCF50633_REG_LDO5OUT,
+ [PCF50633_REGULATOR_LDO6] = PCF50633_REG_LDO6OUT,
+ [PCF50633_REGULATOR_HCLDO] = PCF50633_REG_HCLDOOUT,
+};
+
+int pcf50633_gpio_set(struct pcf50633 *pcf, int gpio, u8 val)
+{
+ u8 reg;
+
+ reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
+
+ return pcf50633_reg_set_bit_mask(pcf, reg, 0x07, val);
+}
+EXPORT_SYMBOL_GPL(pcf50633_gpio_set);
+
+u8 pcf50633_gpio_get(struct pcf50633 *pcf, int gpio)
+{
+ u8 reg, val;
+
+ reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
+ val = pcf50633_reg_read(pcf, reg) & 0x07;
+
+ return val;
+}
+EXPORT_SYMBOL_GPL(pcf50633_gpio_get);
+
+int pcf50633_gpio_invert_set(struct pcf50633 *pcf, int gpio, int invert)
+{
+ u8 val, reg;
+
+ reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
+ val = !!invert << 3;
+
+ return pcf50633_reg_set_bit_mask(pcf, reg, 1 << 3, val);
+}
+EXPORT_SYMBOL_GPL(pcf50633_gpio_invert_set);
+
+int pcf50633_gpio_invert_get(struct pcf50633 *pcf, int gpio)
+{
+ u8 reg, val;
+
+ reg = gpio - PCF50633_GPIO1 + PCF50633_REG_GPIO1CFG;
+ val = pcf50633_reg_read(pcf, reg);
+
+ return val & (1 << 3);
+}
+EXPORT_SYMBOL_GPL(pcf50633_gpio_invert_get);
+
+int pcf50633_gpio_power_supply_set(struct pcf50633 *pcf,
+ int gpio, int regulator, int on)
+{
+ u8 reg, val, mask;
+
+ /* the *ENA register is always one after the *OUT register */
+ reg = pcf50633_regulator_registers[regulator] + 1;
+
+ val = !!on << (gpio - PCF50633_GPIO1);
+ mask = 1 << (gpio - PCF50633_GPIO1);
+
+ return pcf50633_reg_set_bit_mask(pcf, reg, mask, val);
+}
+EXPORT_SYMBOL_GPL(pcf50633_gpio_power_supply_set);
diff --git a/drivers/mfd/sm501.c b/drivers/mfd/sm501.c
index 170f9d4..0e5761f 100644
--- a/drivers/mfd/sm501.c
+++ b/drivers/mfd/sm501.c
@@ -41,6 +41,7 @@ struct sm501_gpio_chip {
struct gpio_chip gpio;
struct sm501_gpio *ourgpio; /* to get back to parent. */
void __iomem *regbase;
+ void __iomem *control; /* address of control reg. */
};
struct sm501_gpio {
@@ -908,6 +909,25 @@ static int sm501_gpio_get(struct gpio_chip *chip, unsigned offset)
return result & 1UL;
}
+static void sm501_gpio_ensure_gpio(struct sm501_gpio_chip *smchip,
+ unsigned long bit)
+{
+ unsigned long ctrl;
+
+ /* check and modify if this pin is not set as gpio. */
+
+ if (readl(smchip->control) & bit) {
+ dev_info(sm501_gpio_to_dev(smchip->ourgpio)->dev,
+ "changing mode of gpio, bit %08lx\n", bit);
+
+ ctrl = readl(smchip->control);
+ ctrl &= ~bit;
+ writel(ctrl, smchip->control);
+
+ sm501_sync_regs(sm501_gpio_to_dev(smchip->ourgpio));
+ }
+}
+
static void sm501_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
{
@@ -929,6 +949,8 @@ static void sm501_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
writel(val, regs);
sm501_sync_regs(sm501_gpio_to_dev(smgpio));
+ sm501_gpio_ensure_gpio(smchip, bit);
+
spin_unlock_irqrestore(&smgpio->lock, save);
}
@@ -941,8 +963,8 @@ static int sm501_gpio_input(struct gpio_chip *chip, unsigned offset)
unsigned long save;
unsigned long ddr;
- dev_info(sm501_gpio_to_dev(smgpio)->dev, "%s(%p,%d)\n",
- __func__, chip, offset);
+ dev_dbg(sm501_gpio_to_dev(smgpio)->dev, "%s(%p,%d)\n",
+ __func__, chip, offset);
spin_lock_irqsave(&smgpio->lock, save);
@@ -950,6 +972,8 @@ static int sm501_gpio_input(struct gpio_chip *chip, unsigned offset)
writel(ddr & ~bit, regs + SM501_GPIO_DDR_LOW);
sm501_sync_regs(sm501_gpio_to_dev(smgpio));
+ sm501_gpio_ensure_gpio(smchip, bit);
+
spin_unlock_irqrestore(&smgpio->lock, save);
return 0;
@@ -1012,9 +1036,11 @@ static int __devinit sm501_gpio_register_chip(struct sm501_devdata *sm,
if (base > 0)
base += 32;
chip->regbase = gpio->regs + SM501_GPIO_DATA_HIGH;
+ chip->control = sm->regs + SM501_GPIO63_32_CONTROL;
gchip->label = "SM501-HIGH";
} else {
chip->regbase = gpio->regs + SM501_GPIO_DATA_LOW;
+ chip->control = sm->regs + SM501_GPIO31_0_CONTROL;
gchip->label = "SM501-LOW";
}
diff --git a/drivers/mfd/twl4030-core.c b/drivers/mfd/twl4030-core.c
index b59c385..e7ab003 100644
--- a/drivers/mfd/twl4030-core.c
+++ b/drivers/mfd/twl4030-core.c
@@ -38,6 +38,9 @@
#include <linux/i2c.h>
#include <linux/i2c/twl4030.h>
+#ifdef CONFIG_ARM
+#include <mach/cpu.h>
+#endif
/*
* The TWL4030 "Triton 2" is one of a family of a multi-function "Power
@@ -646,7 +649,7 @@ static inline int __init unprotect_pm_master(void)
return e;
}
-static void __init clocks_init(void)
+static void __init clocks_init(struct device *dev)
{
int e = 0;
struct clk *osc;
@@ -655,9 +658,9 @@ static void __init clocks_init(void)
#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
if (cpu_is_omap2430())
- osc = clk_get(NULL, "osc_ck");
+ osc = clk_get(dev, "osc_ck");
else
- osc = clk_get(NULL, "osc_sys_ck");
+ osc = clk_get(dev, "osc_sys_ck");
if (IS_ERR(osc)) {
printk(KERN_WARNING "Skipping twl4030 internal clock init and "
@@ -773,7 +776,7 @@ twl4030_probe(struct i2c_client *client, const struct i2c_device_id *id)
inuse = true;
/* setup clock framework */
- clocks_init();
+ clocks_init(&client->dev);
/* Maybe init the T2 Interrupt subsystem */
if (client->irq
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c
index 89218f7..6576170 100644
--- a/drivers/misc/sgi-xp/xpc_main.c
+++ b/drivers/misc/sgi-xp/xpc_main.c
@@ -318,7 +318,7 @@ xpc_hb_checker(void *ignore)
/* this thread was marked active by xpc_hb_init() */
- set_cpus_allowed_ptr(current, &cpumask_of_cpu(XPC_HB_CHECK_CPU));
+ set_cpus_allowed_ptr(current, cpumask_of(XPC_HB_CHECK_CPU));
/* set our heartbeating to other partitions into motion */
xpc_hb_check_timeout = jiffies + (xpc_hb_check_interval * HZ);
diff --git a/drivers/net/3c503.c b/drivers/net/3c503.c
index c092c39..5b91a85 100644
--- a/drivers/net/3c503.c
+++ b/drivers/net/3c503.c
@@ -177,6 +177,7 @@ static const struct net_device_ops el2_netdev_ops = {
.ndo_get_stats = eip_get_stats,
.ndo_set_multicast_list = eip_set_multicast_list,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = eip_poll,
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 665e7fd..cdbbb62 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -3109,6 +3109,8 @@ static void acpi_set_WOL(struct net_device *dev)
struct vortex_private *vp = netdev_priv(dev);
void __iomem *ioaddr = vp->ioaddr;
+ device_set_wakeup_enable(vp->gendev, vp->enable_wol);
+
if (vp->enable_wol) {
/* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */
EL3WINDOW(7);
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index dd7ac82..4e19ae3 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -1821,6 +1821,7 @@ static const struct net_device_ops cp_netdev_ops = {
.ndo_open = cp_open,
.ndo_stop = cp_close,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_set_multicast_list = cp_set_rx_mode,
.ndo_get_stats = cp_get_stats,
.ndo_do_ioctl = cp_ioctl,
@@ -1832,6 +1833,7 @@ static const struct net_device_ops cp_netdev_ops = {
#ifdef BROKEN
.ndo_change_mtu = cp_change_mtu,
#endif
+
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = cp_poll_controller,
#endif
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index fe370f8..a5b2420 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -917,6 +917,7 @@ static const struct net_device_ops rtl8139_netdev_ops = {
.ndo_stop = rtl8139_close,
.ndo_get_stats = rtl8139_get_stats,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_start_xmit = rtl8139_start_xmit,
.ndo_set_multicast_list = rtl8139_set_rx_mode,
.ndo_do_ioctl = netdev_ioctl,
@@ -924,7 +925,6 @@ static const struct net_device_ops rtl8139_netdev_ops = {
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = rtl8139_poll_controller,
#endif
-
};
static int __devinit rtl8139_init_one (struct pci_dev *pdev,
diff --git a/drivers/net/8390.c b/drivers/net/8390.c
index fbe609a..ec3e22e 100644
--- a/drivers/net/8390.c
+++ b/drivers/net/8390.c
@@ -63,6 +63,7 @@ const struct net_device_ops ei_netdev_ops = {
.ndo_get_stats = ei_get_stats,
.ndo_set_multicast_list = ei_set_multicast_list,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ei_poll,
diff --git a/drivers/net/8390p.c b/drivers/net/8390p.c
index ee70b35..da863c9 100644
--- a/drivers/net/8390p.c
+++ b/drivers/net/8390p.c
@@ -68,6 +68,7 @@ const struct net_device_ops eip_netdev_ops = {
.ndo_get_stats = eip_get_stats,
.ndo_set_multicast_list = eip_set_multicast_list,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = eip_poll,
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 65afda4..9fe8cb7 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1600,7 +1600,7 @@ config 8139_OLD_RX_RESET
old RX-reset behavior. If unsure, say N.
config R6040
- tristate "RDC R6040 Fast Ethernet Adapter support (EXPERIMENTAL)"
+ tristate "RDC R6040 Fast Ethernet Adapter support"
depends on NET_PCI && PCI
select CRC32
select MII
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index 5b396ff..9589d620 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -460,6 +460,7 @@ static const struct net_device_ops ace_netdev_ops = {
.ndo_get_stats = ace_get_stats,
.ndo_start_xmit = ace_start_xmit,
.ndo_set_multicast_list = ace_set_multicast_list,
+ .ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = ace_set_mac_addr,
.ndo_change_mtu = ace_change_mtu,
#if ACENIC_DO_VLAN
diff --git a/drivers/net/arm/etherh.c b/drivers/net/arm/etherh.c
index 6278606..745ac18 100644
--- a/drivers/net/arm/etherh.c
+++ b/drivers/net/arm/etherh.c
@@ -646,6 +646,7 @@ static const struct net_device_ops etherh_netdev_ops = {
.ndo_get_stats = ei_get_stats,
.ndo_set_multicast_list = ei_set_multicast_list,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_addr = eth_set_mac_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ei_poll,
diff --git a/drivers/net/arm/ks8695net.c b/drivers/net/arm/ks8695net.c
index 9ad22d1..1cf2f94 100644
--- a/drivers/net/arm/ks8695net.c
+++ b/drivers/net/arm/ks8695net.c
@@ -1357,6 +1357,7 @@ static const struct net_device_ops ks8695_netdev_ops = {
.ndo_start_xmit = ks8695_start_xmit,
.ndo_tx_timeout = ks8695_timeout,
.ndo_set_mac_address = ks8695_set_mac,
+ .ndo_validate_addr = eth_validate_addr,
.ndo_set_multicast_list = ks8695_set_multicast,
};
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 6926ebe..5ae131c 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -73,8 +73,8 @@
(BP)->tx_cons - (BP)->tx_prod - TX_RING_GAP(BP))
#define NEXT_TX(N) (((N) + 1) & (B44_TX_RING_SIZE - 1))
-#define RX_PKT_OFFSET 30
-#define RX_PKT_BUF_SZ (1536 + RX_PKT_OFFSET + 64)
+#define RX_PKT_OFFSET (RX_HEADER_LEN + 2)
+#define RX_PKT_BUF_SZ (1536 + RX_PKT_OFFSET)
/* minimum number of free TX descriptors required to wake up TX process */
#define B44_TX_WAKEUP_THRESH (B44_TX_RING_SIZE / 4)
@@ -682,7 +682,6 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
}
rh = (struct rx_header *) skb->data;
- skb_reserve(skb, RX_PKT_OFFSET);
rh->len = 0;
rh->flags = 0;
@@ -693,13 +692,13 @@ static int b44_alloc_rx_skb(struct b44 *bp, int src_idx, u32 dest_idx_unmasked)
if (src_map != NULL)
src_map->skb = NULL;
- ctrl = (DESC_CTRL_LEN & (RX_PKT_BUF_SZ - RX_PKT_OFFSET));
+ ctrl = (DESC_CTRL_LEN & RX_PKT_BUF_SZ);
if (dest_idx == (B44_RX_RING_SIZE - 1))
ctrl |= DESC_CTRL_EOT;
dp = &bp->rx_ring[dest_idx];
dp->ctrl = cpu_to_le32(ctrl);
- dp->addr = cpu_to_le32((u32) mapping + RX_PKT_OFFSET + bp->dma_offset);
+ dp->addr = cpu_to_le32((u32) mapping + bp->dma_offset);
if (bp->flags & B44_FLAG_RX_RING_HACK)
b44_sync_dma_desc_for_device(bp->sdev, bp->rx_ring_dma,
@@ -809,8 +808,8 @@ static int b44_rx(struct b44 *bp, int budget)
ssb_dma_unmap_single(bp->sdev, map,
skb_size, DMA_FROM_DEVICE);
/* Leave out rx_header */
- skb_put(skb, len + RX_PKT_OFFSET);
- skb_pull(skb, RX_PKT_OFFSET);
+ skb_put(skb, len + RX_PKT_OFFSET);
+ skb_pull(skb, RX_PKT_OFFSET);
} else {
struct sk_buff *copy_skb;
diff --git a/drivers/net/cxgb3/adapter.h b/drivers/net/cxgb3/adapter.h
index 5b346f9..a89d8cc 100644
--- a/drivers/net/cxgb3/adapter.h
+++ b/drivers/net/cxgb3/adapter.h
@@ -50,12 +50,17 @@ struct vlan_group;
struct adapter;
struct sge_qset;
+enum { /* rx_offload flags */
+ T3_RX_CSUM = 1 << 0,
+ T3_LRO = 1 << 1,
+};
+
struct port_info {
struct adapter *adapter;
struct vlan_group *vlan_grp;
struct sge_qset *qs;
u8 port_id;
- u8 rx_csum_offload;
+ u8 rx_offload;
u8 nqsets;
u8 first_qset;
struct cphy phy;
diff --git a/drivers/net/cxgb3/cxgb3_main.c b/drivers/net/cxgb3/cxgb3_main.c
index 2847f94..0089746 100644
--- a/drivers/net/cxgb3/cxgb3_main.c
+++ b/drivers/net/cxgb3/cxgb3_main.c
@@ -546,7 +546,7 @@ static int setup_sge_qsets(struct adapter *adap)
pi->qs = &adap->sge.qs[pi->first_qset];
for (j = pi->first_qset; j < pi->first_qset + pi->nqsets;
++j, ++qset_idx) {
- set_qset_lro(dev, qset_idx, pi->rx_csum_offload);
+ set_qset_lro(dev, qset_idx, pi->rx_offload & T3_LRO);
err = t3_sge_alloc_qset(adap, qset_idx, 1,
(adap->flags & USING_MSIX) ? qset_idx + 1 :
irq_idx,
@@ -1657,17 +1657,19 @@ static u32 get_rx_csum(struct net_device *dev)
{
struct port_info *p = netdev_priv(dev);
- return p->rx_csum_offload;
+ return p->rx_offload & T3_RX_CSUM;
}
static int set_rx_csum(struct net_device *dev, u32 data)
{
struct port_info *p = netdev_priv(dev);
- p->rx_csum_offload = data;
- if (!data) {
+ if (data) {
+ p->rx_offload |= T3_RX_CSUM;
+ } else {
int i;
+ p->rx_offload &= ~(T3_RX_CSUM | T3_LRO);
for (i = p->first_qset; i < p->first_qset + p->nqsets; i++)
set_qset_lro(dev, i, 0);
}
@@ -1830,15 +1832,18 @@ static int cxgb3_set_flags(struct net_device *dev, u32 data)
int i;
if (data & ETH_FLAG_LRO) {
- if (!pi->rx_csum_offload)
+ if (!(pi->rx_offload & T3_RX_CSUM))
return -EINVAL;
+ pi->rx_offload |= T3_LRO;
for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; i++)
set_qset_lro(dev, i, 1);
- } else
+ } else {
+ pi->rx_offload &= ~T3_LRO;
for (i = pi->first_qset; i < pi->first_qset + pi->nqsets; i++)
set_qset_lro(dev, i, 0);
+ }
return 0;
}
@@ -1926,7 +1931,7 @@ static int cxgb_extension_ioctl(struct net_device *dev, void __user *useraddr)
pi = adap2pinfo(adapter, i);
if (t.qset_idx >= pi->first_qset &&
t.qset_idx < pi->first_qset + pi->nqsets &&
- !pi->rx_csum_offload)
+ !(pi->rx_offload & T3_RX_CSUM))
return -EINVAL;
}
@@ -2946,7 +2951,7 @@ static int __devinit init_one(struct pci_dev *pdev,
adapter->port[i] = netdev;
pi = netdev_priv(netdev);
pi->adapter = adapter;
- pi->rx_csum_offload = 1;
+ pi->rx_offload = T3_RX_CSUM | T3_LRO;
pi->port_id = i;
netif_carrier_off(netdev);
netif_tx_stop_all_queues(netdev);
@@ -2955,6 +2960,7 @@ static int __devinit init_one(struct pci_dev *pdev,
netdev->mem_end = mmio_start + mmio_len - 1;
netdev->features |= NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_TSO;
netdev->features |= NETIF_F_LLTX;
+ netdev->features |= NETIF_F_LRO;
if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA;
diff --git a/drivers/net/cxgb3/sge.c b/drivers/net/cxgb3/sge.c
index 6c641a8..14f9fb3 100644
--- a/drivers/net/cxgb3/sge.c
+++ b/drivers/net/cxgb3/sge.c
@@ -1932,7 +1932,7 @@ static void rx_eth(struct adapter *adap, struct sge_rspq *rq,
skb_pull(skb, sizeof(*p) + pad);
skb->protocol = eth_type_trans(skb, adap->port[p->iff]);
pi = netdev_priv(skb->dev);
- if (pi->rx_csum_offload && p->csum_valid && p->csum == htons(0xffff) &&
+ if ((pi->rx_offload & T3_RX_CSUM) && p->csum_valid && p->csum == htons(0xffff) &&
!p->fragment) {
qs->port_stats[SGE_PSTAT_RX_CSUM_GOOD]++;
skb->ip_summed = CHECKSUM_UNNECESSARY;
diff --git a/drivers/net/e1000e/ich8lan.c b/drivers/net/e1000e/ich8lan.c
index f2a5963..e415e81 100644
--- a/drivers/net/e1000e/ich8lan.c
+++ b/drivers/net/e1000e/ich8lan.c
@@ -390,7 +390,8 @@ static s32 e1000_get_variants_ich8lan(struct e1000_adapter *adapter)
}
static DEFINE_MUTEX(nvm_mutex);
-static pid_t nvm_owner = -1;
+static pid_t nvm_owner_pid = -1;
+static char nvm_owner_name[TASK_COMM_LEN] = "";
/**
* e1000_acquire_swflag_ich8lan - Acquire software control flag
@@ -408,11 +409,15 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
might_sleep();
if (!mutex_trylock(&nvm_mutex)) {
- WARN(1, KERN_ERR "e1000e mutex contention. Owned by pid %d\n",
- nvm_owner);
+ WARN(1, KERN_ERR "e1000e mutex contention. Owned by process "
+ "%s (pid %d), required by process %s (pid %d)\n",
+ nvm_owner_name, nvm_owner_pid,
+ current->comm, current->pid);
+
mutex_lock(&nvm_mutex);
}
- nvm_owner = current->pid;
+ nvm_owner_pid = current->pid;
+ strncpy(nvm_owner_name, current->comm, TASK_COMM_LEN);
while (timeout) {
extcnf_ctrl = er32(EXTCNF_CTRL);
@@ -430,7 +435,8 @@ static s32 e1000_acquire_swflag_ich8lan(struct e1000_hw *hw)
hw_dbg(hw, "FW or HW has locked the resource for too long.\n");
extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
ew32(EXTCNF_CTRL, extcnf_ctrl);
- nvm_owner = -1;
+ nvm_owner_pid = -1;
+ strcpy(nvm_owner_name, "");
mutex_unlock(&nvm_mutex);
return -E1000_ERR_CONFIG;
}
@@ -454,7 +460,8 @@ static void e1000_release_swflag_ich8lan(struct e1000_hw *hw)
extcnf_ctrl &= ~E1000_EXTCNF_CTRL_SWFLAG;
ew32(EXTCNF_CTRL, extcnf_ctrl);
- nvm_owner = -1;
+ nvm_owner_pid = -1;
+ strcpy(nvm_owner_name, "");
mutex_unlock(&nvm_mutex);
}
diff --git a/drivers/net/e2100.c b/drivers/net/e2100.c
index 20eb05c..b07ba19 100644
--- a/drivers/net/e2100.c
+++ b/drivers/net/e2100.c
@@ -169,6 +169,7 @@ static const struct net_device_ops e21_netdev_ops = {
.ndo_get_stats = ei_get_stats,
.ndo_set_multicast_list = ei_set_multicast_list,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ei_poll,
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index d039e16..7d60551 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1599,6 +1599,7 @@ static const struct net_device_ops enic_netdev_ops = {
.ndo_start_xmit = enic_hard_start_xmit,
.ndo_get_stats = enic_get_stats,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_set_multicast_list = enic_set_multicast_list,
.ndo_change_mtu = enic_change_mtu,
.ndo_vlan_rx_register = enic_vlan_rx_register,
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 5b68dc2..5b910cf 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -13,7 +13,7 @@
* Copyright (C) 2004 Andrew de Quincey (wol support)
* Copyright (C) 2004 Carl-Daniel Hailfinger (invalid MAC handling, insane
* IRQ rate fixes, bigendian fixes, cleanups, verification)
- * Copyright (c) 2004,2005,2006,2007,2008 NVIDIA Corporation
+ * Copyright (c) 2004,2005,2006,2007,2008,2009 NVIDIA 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
@@ -39,7 +39,7 @@
* DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
* superfluous timer interrupts from the nic.
*/
-#define FORCEDETH_VERSION "0.61"
+#define FORCEDETH_VERSION "0.62"
#define DRV_NAME "forcedeth"
#include <linux/module.h>
@@ -2096,14 +2096,15 @@ static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
((skb_shinfo(skb)->frags[i].size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
}
+ spin_lock_irqsave(&np->lock, flags);
empty_slots = nv_get_empty_tx_slots(np);
if (unlikely(empty_slots <= entries)) {
- spin_lock_irqsave(&np->lock, flags);
netif_stop_queue(dev);
np->tx_stop = 1;
spin_unlock_irqrestore(&np->lock, flags);
return NETDEV_TX_BUSY;
}
+ spin_unlock_irqrestore(&np->lock, flags);
start_tx = put_tx = np->put_tx.orig;
@@ -2214,14 +2215,15 @@ static int nv_start_xmit_optimized(struct sk_buff *skb, struct net_device *dev)
((skb_shinfo(skb)->frags[i].size & (NV_TX2_TSO_MAX_SIZE-1)) ? 1 : 0);
}
+ spin_lock_irqsave(&np->lock, flags);
empty_slots = nv_get_empty_tx_slots(np);
if (unlikely(empty_slots <= entries)) {
- spin_lock_irqsave(&np->lock, flags);
netif_stop_queue(dev);
np->tx_stop = 1;
spin_unlock_irqrestore(&np->lock, flags);
return NETDEV_TX_BUSY;
}
+ spin_unlock_irqrestore(&np->lock, flags);
start_tx = put_tx = np->put_tx.ex;
start_tx_ctx = np->put_tx_ctx;
@@ -3403,10 +3405,10 @@ static irqreturn_t nv_nic_irq(int foo, void *data)
#ifdef CONFIG_FORCEDETH_NAPI
if (events & NVREG_IRQ_RX_ALL) {
+ spin_lock(&np->lock);
netif_rx_schedule(&np->napi);
/* Disable furthur receive irq's */
- spin_lock(&np->lock);
np->irqmask &= ~NVREG_IRQ_RX_ALL;
if (np->msi_flags & NV_MSI_X_ENABLED)
@@ -3520,10 +3522,10 @@ static irqreturn_t nv_nic_irq_optimized(int foo, void *data)
#ifdef CONFIG_FORCEDETH_NAPI
if (events & NVREG_IRQ_RX_ALL) {
+ spin_lock(&np->lock);
netif_rx_schedule(&np->napi);
/* Disable furthur receive irq's */
- spin_lock(&np->lock);
np->irqmask &= ~NVREG_IRQ_RX_ALL;
if (np->msi_flags & NV_MSI_X_ENABLED)
@@ -6167,19 +6169,19 @@ static struct pci_device_id pci_tbl[] = {
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_36),
- .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_37),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_38),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
},
{ /* MCP79 Ethernet Controller */
PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_39),
- .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_MGMT_UNIT|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
+ .driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA|DEV_HAS_MSI|DEV_HAS_POWER_CNTRL|DEV_HAS_PAUSEFRAME_TX_V3|DEV_HAS_STATISTICS_V3|DEV_HAS_TEST_EXTENDED|DEV_HAS_CORRECT_MACADDR|DEV_HAS_COLLISION_FIX|DEV_NEED_TX_LIMIT|DEV_HAS_GEAR_MODE,
},
{0,},
};
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c
index 1b8deca..efcbeb6 100644
--- a/drivers/net/gianfar.c
+++ b/drivers/net/gianfar.c
@@ -296,6 +296,20 @@ err_out:
return err;
}
+/* Ioctl MII Interface */
+static int gfar_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct gfar_private *priv = netdev_priv(dev);
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ if (!priv->phydev)
+ return -ENODEV;
+
+ return phy_mii_ioctl(priv->phydev, if_mii(rq), cmd);
+}
+
/* Set up the ethernet device structure, private data,
* and anything else we need before we start */
static int gfar_probe(struct of_device *ofdev,
@@ -366,6 +380,7 @@ static int gfar_probe(struct of_device *ofdev,
dev->set_multicast_list = gfar_set_multi;
dev->ethtool_ops = &gfar_ethtool_ops;
+ dev->do_ioctl = gfar_ioctl;
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_CSUM) {
priv->rx_csum_enable = 1;
diff --git a/drivers/net/hamachi.c b/drivers/net/hamachi.c
index 3220022..7e8b3c5 100644
--- a/drivers/net/hamachi.c
+++ b/drivers/net/hamachi.c
@@ -576,6 +576,7 @@ static const struct net_device_ops hamachi_netdev_ops = {
.ndo_set_multicast_list = set_rx_mode,
.ndo_change_mtu = eth_change_mtu,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_tx_timeout = hamachi_tx_timeout,
.ndo_do_ioctl = netdev_ioctl,
};
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 50f1e17..2d40898 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -717,11 +717,12 @@ static int sixpack_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct sixpack *sp = sp_get(tty);
- struct net_device *dev = sp->dev;
+ struct net_device *dev;
unsigned int tmp, err;
if (!sp)
return -ENXIO;
+ dev = sp->dev;
switch(cmd) {
case SIOCGIFNAME:
diff --git a/drivers/net/hp-plus.c b/drivers/net/hp-plus.c
index b507dbc..5e070f4 100644
--- a/drivers/net/hp-plus.c
+++ b/drivers/net/hp-plus.c
@@ -166,6 +166,7 @@ static const struct net_device_ops hpp_netdev_ops = {
.ndo_get_stats = eip_get_stats,
.ndo_set_multicast_list = eip_set_multicast_list,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = eip_poll,
diff --git a/drivers/net/hydra.c b/drivers/net/hydra.c
index 9cb38a8..8ac0930 100644
--- a/drivers/net/hydra.c
+++ b/drivers/net/hydra.c
@@ -103,6 +103,7 @@ static const struct net_device_ops hydra_netdev_ops = {
.ndo_get_stats = ei_get_stats,
.ndo_set_multicast_list = ei_set_multicast_list,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ei_poll,
diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c
index 75a1d0a..9411640 100644
--- a/drivers/net/irda/au1k_ir.c
+++ b/drivers/net/irda/au1k_ir.c
@@ -594,7 +594,7 @@ static int au1k_irda_rx(struct net_device *dev)
update_rx_stats(dev, flags, count);
skb=alloc_skb(count+1,GFP_ATOMIC);
if (skb == NULL) {
- aup->stats.rx_dropped++;
+ aup->netdev->stats.rx_dropped++;
continue;
}
skb_reserve(skb, 1);
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index 687c2d5..6f3e7f7 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -1194,13 +1194,13 @@ toshoboe_interrupt (int irq, void *dev_id)
txp = txpc;
txpc++;
txpc %= TX_SLOTS;
- self->stats.tx_packets++;
+ self->netdev->stats.tx_packets++;
if (self->ring->tx[txpc].control & OBOE_CTL_TX_HW_OWNS)
self->ring->tx[txp].control &= ~OBOE_CTL_TX_RTCENTX;
}
- self->stats.tx_packets--;
+ self->netdev->stats.tx_packets--;
#else
- self->stats.tx_packets++;
+ self->netdev->stats.tx_packets++;
#endif
toshoboe_start_DMA(self, OBOE_CONFIG0H_ENTX);
}
@@ -1280,7 +1280,7 @@ dumpbufs(self->rx_bufs[self->rxs],len,'<');
skb_put (skb, len);
skb_copy_to_linear_data(skb, self->rx_bufs[self->rxs],
len);
- self->stats.rx_packets++;
+ self->netdev->stats.rx_packets++;
skb->dev = self->netdev;
skb_reset_mac_header(skb);
skb->protocol = htons (ETH_P_IRDA);
diff --git a/drivers/net/mac8390.c b/drivers/net/mac8390.c
index 57716e2..8e88486 100644
--- a/drivers/net/mac8390.c
+++ b/drivers/net/mac8390.c
@@ -486,6 +486,7 @@ static const struct net_device_ops mac8390_netdev_ops = {
.ndo_get_stats = ei_get_stats,
.ndo_set_multicast_list = ei_set_multicast_list,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ei_poll,
diff --git a/drivers/net/mlx4/en_netdev.c b/drivers/net/mlx4/en_netdev.c
index 15bb38d..9f6644a 100644
--- a/drivers/net/mlx4/en_netdev.c
+++ b/drivers/net/mlx4/en_netdev.c
@@ -952,6 +952,7 @@ static const struct net_device_ops mlx4_netdev_ops = {
.ndo_get_stats = mlx4_en_get_stats,
.ndo_set_multicast_list = mlx4_en_set_multicast,
.ndo_set_mac_address = mlx4_en_set_mac,
+ .ndo_validate_addr = eth_validate_addr,
.ndo_change_mtu = mlx4_en_change_mtu,
.ndo_tx_timeout = mlx4_en_tx_timeout,
.ndo_vlan_rx_register = mlx4_en_vlan_rx_register,
diff --git a/drivers/net/mlx4/main.c b/drivers/net/mlx4/main.c
index 710c79e..6ef2490 100644
--- a/drivers/net/mlx4/main.c
+++ b/drivers/net/mlx4/main.c
@@ -912,8 +912,8 @@ static void mlx4_enable_msi_x(struct mlx4_dev *dev)
int i;
if (msi_x) {
- nreq = min(dev->caps.num_eqs - dev->caps.reserved_eqs,
- num_possible_cpus() + 1);
+ nreq = min_t(int, dev->caps.num_eqs - dev->caps.reserved_eqs,
+ num_possible_cpus() + 1);
entries = kcalloc(nreq, sizeof *entries, GFP_KERNEL);
if (!entries)
goto no_msi;
diff --git a/drivers/net/ne-h8300.c b/drivers/net/ne-h8300.c
index b572391..7bd6662 100644
--- a/drivers/net/ne-h8300.c
+++ b/drivers/net/ne-h8300.c
@@ -202,6 +202,7 @@ static const struct net_device_ops ne_netdev_ops = {
.ndo_get_stats = ei_get_stats,
.ndo_set_multicast_list = ei_set_multicast_list,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ei_poll,
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index 62f20ba..f090d3b 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -208,6 +208,7 @@ static const struct net_device_ops ne2k_netdev_ops = {
.ndo_get_stats = ei_get_stats,
.ndo_set_multicast_list = ei_set_multicast_list,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ei_poll,
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index 42021ac..e80294d 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -1956,6 +1956,7 @@ static const struct net_device_ops netdev_ops = {
.ndo_change_mtu = ns83820_change_mtu,
.ndo_set_multicast_list = ns83820_set_multicast,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_tx_timeout = ns83820_tx_timeout,
#ifdef NS83820_VLAN_ACCEL_SUPPORT
.ndo_vlan_rx_register = ns83820_vlan_rx_register,
diff --git a/drivers/net/qlge/qlge.h b/drivers/net/qlge/qlge.h
index 459663a..c1dadad 100644
--- a/drivers/net/qlge/qlge.h
+++ b/drivers/net/qlge/qlge.h
@@ -28,11 +28,11 @@
} while (0)
#define QLGE_VENDOR_ID 0x1077
-#define QLGE_DEVICE_ID1 0x8012
-#define QLGE_DEVICE_ID 0x8000
+#define QLGE_DEVICE_ID 0x8012
-#define MAX_RX_RINGS 128
-#define MAX_TX_RINGS 128
+#define MAX_CPUS 8
+#define MAX_TX_RINGS MAX_CPUS
+#define MAX_RX_RINGS ((MAX_CPUS * 2) + 1)
#define NUM_TX_RING_ENTRIES 256
#define NUM_RX_RING_ENTRIES 256
@@ -45,6 +45,7 @@
#define MAX_SPLIT_SIZE 1023
#define QLGE_SB_PAD 32
+#define MAX_CQ 128
#define DFLT_COALESCE_WAIT 100 /* 100 usec wait for coalescing */
#define MAX_INTER_FRAME_WAIT 10 /* 10 usec max interframe-wait for coalescing */
#define DFLT_INTER_FRAME_WAIT (MAX_INTER_FRAME_WAIT/2)
@@ -961,8 +962,7 @@ struct ib_mac_iocb_rsp {
#define IB_MAC_IOCB_RSP_DS 0x40 /* data is in small buffer */
#define IB_MAC_IOCB_RSP_DL 0x80 /* data is in large buffer */
__le32 data_len; /* */
- __le32 data_addr_lo; /* */
- __le32 data_addr_hi; /* */
+ __le64 data_addr; /* */
__le32 rss; /* */
__le16 vlan_id; /* 12 bits */
#define IB_MAC_IOCB_RSP_C 0x1000 /* VLAN CFI bit */
@@ -976,8 +976,7 @@ struct ib_mac_iocb_rsp {
#define IB_MAC_IOCB_RSP_HS 0x40
#define IB_MAC_IOCB_RSP_HL 0x80
__le32 hdr_len; /* */
- __le32 hdr_addr_lo; /* */
- __le32 hdr_addr_hi; /* */
+ __le64 hdr_addr; /* */
} __attribute((packed));
struct ib_ae_iocb_rsp {
@@ -1042,10 +1041,8 @@ struct wqicb {
__le16 cq_id_rss;
#define Q_CQ_ID_RSS_RV 0x8000
__le16 rid;
- __le32 addr_lo;
- __le32 addr_hi;
- __le32 cnsmr_idx_addr_lo;
- __le32 cnsmr_idx_addr_hi;
+ __le64 addr;
+ __le64 cnsmr_idx_addr;
} __attribute((packed));
/*
@@ -1070,18 +1067,14 @@ struct cqicb {
#define LEN_CPP_64 0x0002
#define LEN_CPP_128 0x0003
__le16 rid;
- __le32 addr_lo;
- __le32 addr_hi;
- __le32 prod_idx_addr_lo;
- __le32 prod_idx_addr_hi;
+ __le64 addr;
+ __le64 prod_idx_addr;
__le16 pkt_delay;
__le16 irq_delay;
- __le32 lbq_addr_lo;
- __le32 lbq_addr_hi;
+ __le64 lbq_addr;
__le16 lbq_buf_size;
__le16 lbq_len; /* entry count */
- __le32 sbq_addr_lo;
- __le32 sbq_addr_hi;
+ __le64 sbq_addr;
__le16 sbq_buf_size;
__le16 sbq_len; /* entry count */
} __attribute((packed));
@@ -1145,7 +1138,7 @@ struct tx_ring {
struct wqicb wqicb; /* structure used to inform chip of new queue */
void *wq_base; /* pci_alloc:virtual addr for tx */
dma_addr_t wq_base_dma; /* pci_alloc:dma addr for tx */
- u32 *cnsmr_idx_sh_reg; /* shadow copy of consumer idx */
+ __le32 *cnsmr_idx_sh_reg; /* shadow copy of consumer idx */
dma_addr_t cnsmr_idx_sh_reg_dma; /* dma-shadow copy of consumer */
u32 wq_size; /* size in bytes of queue area */
u32 wq_len; /* number of entries in queue */
@@ -1181,7 +1174,7 @@ struct rx_ring {
u32 cq_size;
u32 cq_len;
u16 cq_id;
- volatile __le32 *prod_idx_sh_reg; /* Shadowed producer register. */
+ __le32 *prod_idx_sh_reg; /* Shadowed producer register. */
dma_addr_t prod_idx_sh_reg_dma;
void __iomem *cnsmr_idx_db_reg; /* PCI doorbell mem area + 0 */
u32 cnsmr_idx; /* current sw idx */
@@ -1402,9 +1395,11 @@ struct ql_adapter {
int rx_ring_count;
int ring_mem_size;
void *ring_mem;
- struct rx_ring *rx_ring;
+
+ struct rx_ring rx_ring[MAX_RX_RINGS];
+ struct tx_ring tx_ring[MAX_TX_RINGS];
+
int rx_csum;
- struct tx_ring *tx_ring;
u32 default_rx_queue;
u16 rx_coalesce_usecs; /* cqicb->int_delay */
@@ -1459,6 +1454,24 @@ static inline void ql_write_db_reg(u32 val, void __iomem *addr)
mmiowb();
}
+/*
+ * Shadow Registers:
+ * Outbound queues have a consumer index that is maintained by the chip.
+ * Inbound queues have a producer index that is maintained by the chip.
+ * For lower overhead, these registers are "shadowed" to host memory
+ * which allows the device driver to track the queue progress without
+ * PCI reads. When an entry is placed on an inbound queue, the chip will
+ * update the relevant index register and then copy the value to the
+ * shadow register in host memory.
+ */
+static inline u32 ql_read_sh_reg(__le32 *addr)
+{
+ u32 reg;
+ reg = le32_to_cpu(*addr);
+ rmb();
+ return reg;
+}
+
extern char qlge_driver_name[];
extern const char qlge_driver_version[];
extern const struct ethtool_ops qlge_ethtool_ops;
diff --git a/drivers/net/qlge/qlge_dbg.c b/drivers/net/qlge/qlge_dbg.c
index 3f5e02d..379b895 100644
--- a/drivers/net/qlge/qlge_dbg.c
+++ b/drivers/net/qlge/qlge_dbg.c
@@ -435,14 +435,10 @@ void ql_dump_wqicb(struct wqicb *wqicb)
printk(KERN_ERR PFX "wqicb->cq_id_rss = %d.\n",
le16_to_cpu(wqicb->cq_id_rss));
printk(KERN_ERR PFX "wqicb->rid = 0x%x.\n", le16_to_cpu(wqicb->rid));
- printk(KERN_ERR PFX "wqicb->wq_addr_lo = 0x%.08x.\n",
- le32_to_cpu(wqicb->addr_lo));
- printk(KERN_ERR PFX "wqicb->wq_addr_hi = 0x%.08x.\n",
- le32_to_cpu(wqicb->addr_hi));
- printk(KERN_ERR PFX "wqicb->wq_cnsmr_idx_addr_lo = 0x%.08x.\n",
- le32_to_cpu(wqicb->cnsmr_idx_addr_lo));
- printk(KERN_ERR PFX "wqicb->wq_cnsmr_idx_addr_hi = 0x%.08x.\n",
- le32_to_cpu(wqicb->cnsmr_idx_addr_hi));
+ printk(KERN_ERR PFX "wqicb->wq_addr = 0x%llx.\n",
+ (unsigned long long) le64_to_cpu(wqicb->addr));
+ printk(KERN_ERR PFX "wqicb->wq_cnsmr_idx_addr = 0x%llx.\n",
+ (unsigned long long) le64_to_cpu(wqicb->cnsmr_idx_addr));
}
void ql_dump_tx_ring(struct tx_ring *tx_ring)
@@ -455,10 +451,11 @@ void ql_dump_tx_ring(struct tx_ring *tx_ring)
printk(KERN_ERR PFX "tx_ring->base = %p.\n", tx_ring->wq_base);
printk(KERN_ERR PFX "tx_ring->base_dma = 0x%llx.\n",
(unsigned long long) tx_ring->wq_base_dma);
- printk(KERN_ERR PFX "tx_ring->cnsmr_idx_sh_reg = %p.\n",
- tx_ring->cnsmr_idx_sh_reg);
- printk(KERN_ERR PFX "tx_ring->cnsmr_idx_sh_reg_dma = 0x%llx.\n",
- (unsigned long long) tx_ring->cnsmr_idx_sh_reg_dma);
+ printk(KERN_ERR PFX
+ "tx_ring->cnsmr_idx_sh_reg, addr = 0x%p, value = %d.\n",
+ tx_ring->cnsmr_idx_sh_reg,
+ tx_ring->cnsmr_idx_sh_reg
+ ? ql_read_sh_reg(tx_ring->cnsmr_idx_sh_reg) : 0);
printk(KERN_ERR PFX "tx_ring->size = %d.\n", tx_ring->wq_size);
printk(KERN_ERR PFX "tx_ring->len = %d.\n", tx_ring->wq_len);
printk(KERN_ERR PFX "tx_ring->prod_idx_db_reg = %p.\n",
@@ -510,30 +507,22 @@ void ql_dump_cqicb(struct cqicb *cqicb)
printk(KERN_ERR PFX "cqicb->msix_vect = %d.\n", cqicb->msix_vect);
printk(KERN_ERR PFX "cqicb->flags = %x.\n", cqicb->flags);
printk(KERN_ERR PFX "cqicb->len = %d.\n", le16_to_cpu(cqicb->len));
- printk(KERN_ERR PFX "cqicb->addr_lo = %x.\n",
- le32_to_cpu(cqicb->addr_lo));
- printk(KERN_ERR PFX "cqicb->addr_hi = %x.\n",
- le32_to_cpu(cqicb->addr_hi));
- printk(KERN_ERR PFX "cqicb->prod_idx_addr_lo = %x.\n",
- le32_to_cpu(cqicb->prod_idx_addr_lo));
- printk(KERN_ERR PFX "cqicb->prod_idx_addr_hi = %x.\n",
- le32_to_cpu(cqicb->prod_idx_addr_hi));
+ printk(KERN_ERR PFX "cqicb->addr = 0x%llx.\n",
+ (unsigned long long) le64_to_cpu(cqicb->addr));
+ printk(KERN_ERR PFX "cqicb->prod_idx_addr = 0x%llx.\n",
+ (unsigned long long) le64_to_cpu(cqicb->prod_idx_addr));
printk(KERN_ERR PFX "cqicb->pkt_delay = 0x%.04x.\n",
le16_to_cpu(cqicb->pkt_delay));
printk(KERN_ERR PFX "cqicb->irq_delay = 0x%.04x.\n",
le16_to_cpu(cqicb->irq_delay));
- printk(KERN_ERR PFX "cqicb->lbq_addr_lo = %x.\n",
- le32_to_cpu(cqicb->lbq_addr_lo));
- printk(KERN_ERR PFX "cqicb->lbq_addr_hi = %x.\n",
- le32_to_cpu(cqicb->lbq_addr_hi));
+ printk(KERN_ERR PFX "cqicb->lbq_addr = 0x%llx.\n",
+ (unsigned long long) le64_to_cpu(cqicb->lbq_addr));
printk(KERN_ERR PFX "cqicb->lbq_buf_size = 0x%.04x.\n",
le16_to_cpu(cqicb->lbq_buf_size));
printk(KERN_ERR PFX "cqicb->lbq_len = 0x%.04x.\n",
le16_to_cpu(cqicb->lbq_len));
- printk(KERN_ERR PFX "cqicb->sbq_addr_lo = %x.\n",
- le32_to_cpu(cqicb->sbq_addr_lo));
- printk(KERN_ERR PFX "cqicb->sbq_addr_hi = %x.\n",
- le32_to_cpu(cqicb->sbq_addr_hi));
+ printk(KERN_ERR PFX "cqicb->sbq_addr = 0x%llx.\n",
+ (unsigned long long) le64_to_cpu(cqicb->sbq_addr));
printk(KERN_ERR PFX "cqicb->sbq_buf_size = 0x%.04x.\n",
le16_to_cpu(cqicb->sbq_buf_size));
printk(KERN_ERR PFX "cqicb->sbq_len = 0x%.04x.\n",
@@ -558,9 +547,10 @@ void ql_dump_rx_ring(struct rx_ring *rx_ring)
printk(KERN_ERR PFX "rx_ring->cq_size = %d.\n", rx_ring->cq_size);
printk(KERN_ERR PFX "rx_ring->cq_len = %d.\n", rx_ring->cq_len);
printk(KERN_ERR PFX
- "rx_ring->prod_idx_sh_reg, addr = %p, value = %d.\n",
+ "rx_ring->prod_idx_sh_reg, addr = 0x%p, value = %d.\n",
rx_ring->prod_idx_sh_reg,
- rx_ring->prod_idx_sh_reg ? *(rx_ring->prod_idx_sh_reg) : 0);
+ rx_ring->prod_idx_sh_reg
+ ? ql_read_sh_reg(rx_ring->prod_idx_sh_reg) : 0);
printk(KERN_ERR PFX "rx_ring->prod_idx_sh_reg_dma = %llx.\n",
(unsigned long long) rx_ring->prod_idx_sh_reg_dma);
printk(KERN_ERR PFX "rx_ring->cnsmr_idx_db_reg = %p.\n",
@@ -809,10 +799,8 @@ void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp)
printk(KERN_ERR PFX "data_len = %d\n",
le32_to_cpu(ib_mac_rsp->data_len));
- printk(KERN_ERR PFX "data_addr_hi = 0x%x\n",
- le32_to_cpu(ib_mac_rsp->data_addr_hi));
- printk(KERN_ERR PFX "data_addr_lo = 0x%x\n",
- le32_to_cpu(ib_mac_rsp->data_addr_lo));
+ printk(KERN_ERR PFX "data_addr = 0x%llx\n",
+ (unsigned long long) le64_to_cpu(ib_mac_rsp->data_addr));
if (ib_mac_rsp->flags3 & IB_MAC_IOCB_RSP_RSS_MASK)
printk(KERN_ERR PFX "rss = %x\n",
le32_to_cpu(ib_mac_rsp->rss));
@@ -828,10 +816,8 @@ void ql_dump_ib_mac_rsp(struct ib_mac_iocb_rsp *ib_mac_rsp)
if (ib_mac_rsp->flags4 & IB_MAC_IOCB_RSP_HV) {
printk(KERN_ERR PFX "hdr length = %d.\n",
le32_to_cpu(ib_mac_rsp->hdr_len));
- printk(KERN_ERR PFX "hdr addr_hi = 0x%x.\n",
- le32_to_cpu(ib_mac_rsp->hdr_addr_hi));
- printk(KERN_ERR PFX "hdr addr_lo = 0x%x.\n",
- le32_to_cpu(ib_mac_rsp->hdr_addr_lo));
+ printk(KERN_ERR PFX "hdr addr = 0x%llx.\n",
+ (unsigned long long) le64_to_cpu(ib_mac_rsp->hdr_addr));
}
}
#endif
diff --git a/drivers/net/qlge/qlge_main.c b/drivers/net/qlge/qlge_main.c
index f4c0160..45421c8 100644
--- a/drivers/net/qlge/qlge_main.c
+++ b/drivers/net/qlge/qlge_main.c
@@ -76,7 +76,6 @@ MODULE_PARM_DESC(irq_type, "0 = MSI-X, 1 = MSI, 2 = Legacy.");
static struct pci_device_id qlge_pci_tbl[] __devinitdata = {
{PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID)},
- {PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, QLGE_DEVICE_ID1)},
/* required last entry */
{0,}
};
@@ -127,12 +126,12 @@ static int ql_sem_trylock(struct ql_adapter *qdev, u32 sem_mask)
int ql_sem_spinlock(struct ql_adapter *qdev, u32 sem_mask)
{
- unsigned int seconds = 3;
+ unsigned int wait_count = 30;
do {
if (!ql_sem_trylock(qdev, sem_mask))
return 0;
- ssleep(1);
- } while (--seconds);
+ udelay(100);
+ } while (--wait_count);
return -ETIMEDOUT;
}
@@ -1545,7 +1544,7 @@ static void ql_process_chip_ae_intr(struct ql_adapter *qdev,
static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring)
{
struct ql_adapter *qdev = rx_ring->qdev;
- u32 prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg);
+ u32 prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg);
struct ob_mac_iocb_rsp *net_rsp = NULL;
int count = 0;
@@ -1571,7 +1570,7 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring)
}
count++;
ql_update_cq(rx_ring);
- prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg);
+ prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg);
}
ql_write_cq_idx(rx_ring);
if (netif_queue_stopped(qdev->ndev) && net_rsp != NULL) {
@@ -1591,7 +1590,7 @@ static int ql_clean_outbound_rx_ring(struct rx_ring *rx_ring)
static int ql_clean_inbound_rx_ring(struct rx_ring *rx_ring, int budget)
{
struct ql_adapter *qdev = rx_ring->qdev;
- u32 prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg);
+ u32 prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg);
struct ql_net_rsp_iocb *net_rsp;
int count = 0;
@@ -1624,7 +1623,7 @@ static int ql_clean_inbound_rx_ring(struct rx_ring *rx_ring, int budget)
}
count++;
ql_update_cq(rx_ring);
- prod = le32_to_cpu(*rx_ring->prod_idx_sh_reg);
+ prod = ql_read_sh_reg(rx_ring->prod_idx_sh_reg);
if (count == budget)
break;
}
@@ -1787,7 +1786,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
* Check the default queue and wake handler if active.
*/
rx_ring = &qdev->rx_ring[0];
- if (le32_to_cpu(*rx_ring->prod_idx_sh_reg) != rx_ring->cnsmr_idx) {
+ if (ql_read_sh_reg(rx_ring->prod_idx_sh_reg) != rx_ring->cnsmr_idx) {
QPRINTK(qdev, INTR, INFO, "Waking handler for rx_ring[0].\n");
ql_disable_completion_interrupt(qdev, intr_context->intr);
queue_delayed_work_on(smp_processor_id(), qdev->q_workqueue,
@@ -1801,7 +1800,7 @@ static irqreturn_t qlge_isr(int irq, void *dev_id)
*/
for (i = 1; i < qdev->rx_ring_count; i++) {
rx_ring = &qdev->rx_ring[i];
- if (le32_to_cpu(*rx_ring->prod_idx_sh_reg) !=
+ if (ql_read_sh_reg(rx_ring->prod_idx_sh_reg) !=
rx_ring->cnsmr_idx) {
QPRINTK(qdev, INTR, INFO,
"Waking handler for rx_ring[%d].\n", i);
@@ -2356,28 +2355,6 @@ static void ql_tx_ring_clean(struct ql_adapter *qdev)
}
}
-static void ql_free_ring_cb(struct ql_adapter *qdev)
-{
- kfree(qdev->ring_mem);
-}
-
-static int ql_alloc_ring_cb(struct ql_adapter *qdev)
-{
- /* Allocate space for tx/rx ring control blocks. */
- qdev->ring_mem_size =
- (qdev->tx_ring_count * sizeof(struct tx_ring)) +
- (qdev->rx_ring_count * sizeof(struct rx_ring));
- qdev->ring_mem = kmalloc(qdev->ring_mem_size, GFP_KERNEL);
- if (qdev->ring_mem == NULL) {
- return -ENOMEM;
- } else {
- qdev->rx_ring = qdev->ring_mem;
- qdev->tx_ring = qdev->ring_mem +
- (qdev->rx_ring_count * sizeof(struct rx_ring));
- }
- return 0;
-}
-
static void ql_free_mem_resources(struct ql_adapter *qdev)
{
int i;
@@ -2467,12 +2444,9 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
bq_len = (rx_ring->cq_len == 65536) ? 0 : (u16) rx_ring->cq_len;
cqicb->len = cpu_to_le16(bq_len | LEN_V | LEN_CPP_CONT);
- cqicb->addr_lo = cpu_to_le32(rx_ring->cq_base_dma);
- cqicb->addr_hi = cpu_to_le32((u64) rx_ring->cq_base_dma >> 32);
+ cqicb->addr = cpu_to_le64(rx_ring->cq_base_dma);
- cqicb->prod_idx_addr_lo = cpu_to_le32(rx_ring->prod_idx_sh_reg_dma);
- cqicb->prod_idx_addr_hi =
- cpu_to_le32((u64) rx_ring->prod_idx_sh_reg_dma >> 32);
+ cqicb->prod_idx_addr = cpu_to_le64(rx_ring->prod_idx_sh_reg_dma);
/*
* Set up the control block load flags.
@@ -2483,10 +2457,8 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
if (rx_ring->lbq_len) {
cqicb->flags |= FLAGS_LL; /* Load lbq values */
*((u64 *) rx_ring->lbq_base_indirect) = rx_ring->lbq_base_dma;
- cqicb->lbq_addr_lo =
- cpu_to_le32(rx_ring->lbq_base_indirect_dma);
- cqicb->lbq_addr_hi =
- cpu_to_le32((u64) rx_ring->lbq_base_indirect_dma >> 32);
+ cqicb->lbq_addr =
+ cpu_to_le64(rx_ring->lbq_base_indirect_dma);
bq_len = (rx_ring->lbq_buf_size == 65536) ? 0 :
(u16) rx_ring->lbq_buf_size;
cqicb->lbq_buf_size = cpu_to_le16(bq_len);
@@ -2501,10 +2473,8 @@ static int ql_start_rx_ring(struct ql_adapter *qdev, struct rx_ring *rx_ring)
if (rx_ring->sbq_len) {
cqicb->flags |= FLAGS_LS; /* Load sbq values */
*((u64 *) rx_ring->sbq_base_indirect) = rx_ring->sbq_base_dma;
- cqicb->sbq_addr_lo =
- cpu_to_le32(rx_ring->sbq_base_indirect_dma);
- cqicb->sbq_addr_hi =
- cpu_to_le32((u64) rx_ring->sbq_base_indirect_dma >> 32);
+ cqicb->sbq_addr =
+ cpu_to_le64(rx_ring->sbq_base_indirect_dma);
cqicb->sbq_buf_size =
cpu_to_le16(((rx_ring->sbq_buf_size / 2) + 8) & 0xfffffff8);
bq_len = (rx_ring->sbq_len == 65536) ? 0 :
@@ -2611,12 +2581,9 @@ static int ql_start_tx_ring(struct ql_adapter *qdev, struct tx_ring *tx_ring)
Q_FLAGS_LB | Q_FLAGS_LI | Q_FLAGS_LO);
wqicb->cq_id_rss = cpu_to_le16(tx_ring->cq_id);
wqicb->rid = 0;
- wqicb->addr_lo = cpu_to_le32(tx_ring->wq_base_dma);
- wqicb->addr_hi = cpu_to_le32((u64) tx_ring->wq_base_dma >> 32);
+ wqicb->addr = cpu_to_le64(tx_ring->wq_base_dma);
- wqicb->cnsmr_idx_addr_lo = cpu_to_le32(tx_ring->cnsmr_idx_sh_reg_dma);
- wqicb->cnsmr_idx_addr_hi =
- cpu_to_le32((u64) tx_ring->cnsmr_idx_sh_reg_dma >> 32);
+ wqicb->cnsmr_idx_addr = cpu_to_le64(tx_ring->cnsmr_idx_sh_reg_dma);
ql_init_tx_ring(qdev, tx_ring);
@@ -2746,14 +2713,14 @@ static void ql_resolve_queues_to_irqs(struct ql_adapter *qdev)
* Outbound queue is for outbound completions only.
*/
intr_context->handler = qlge_msix_tx_isr;
- sprintf(intr_context->name, "%s-txq-%d",
+ sprintf(intr_context->name, "%s-tx-%d",
qdev->ndev->name, i);
} else {
/*
* Inbound queues handle unicast frames only.
*/
intr_context->handler = qlge_msix_rx_isr;
- sprintf(intr_context->name, "%s-rxq-%d",
+ sprintf(intr_context->name, "%s-rx-%d",
qdev->ndev->name, i);
}
}
@@ -3247,7 +3214,6 @@ static int qlge_close(struct net_device *ndev)
msleep(1);
ql_adapter_down(qdev);
ql_release_adapter_resources(qdev);
- ql_free_ring_cb(qdev);
return 0;
}
@@ -3273,8 +3239,8 @@ static int ql_configure_rings(struct ql_adapter *qdev)
* This limitation can be removed when requested.
*/
- if (cpu_cnt > 8)
- cpu_cnt = 8;
+ if (cpu_cnt > MAX_CPUS)
+ cpu_cnt = MAX_CPUS;
/*
* rx_ring[0] is always the default queue.
@@ -3294,9 +3260,6 @@ static int ql_configure_rings(struct ql_adapter *qdev)
*/
qdev->rx_ring_count = qdev->tx_ring_count + qdev->rss_ring_count + 1;
- if (ql_alloc_ring_cb(qdev))
- return -ENOMEM;
-
for (i = 0; i < qdev->tx_ring_count; i++) {
tx_ring = &qdev->tx_ring[i];
memset((void *)tx_ring, 0, sizeof(tx_ring));
@@ -3393,7 +3356,6 @@ static int qlge_open(struct net_device *ndev)
error_up:
ql_release_adapter_resources(qdev);
- ql_free_ring_cb(qdev);
return err;
}
diff --git a/drivers/net/r6040.c b/drivers/net/r6040.c
index cf3a082..72fd9e9 100644
--- a/drivers/net/r6040.c
+++ b/drivers/net/r6040.c
@@ -49,8 +49,8 @@
#include <asm/processor.h>
#define DRV_NAME "r6040"
-#define DRV_VERSION "0.20"
-#define DRV_RELDATE "07Jan2009"
+#define DRV_VERSION "0.21"
+#define DRV_RELDATE "09Jan2009"
/* PHY CHIP Address */
#define PHY1_ADDR 1 /* For MAC1 */
@@ -457,22 +457,12 @@ static void r6040_down(struct net_device *dev)
iowrite16(adrp[0], ioaddr + MID_0L);
iowrite16(adrp[1], ioaddr + MID_0M);
iowrite16(adrp[2], ioaddr + MID_0H);
- free_irq(dev->irq, dev);
-
- /* Free RX buffer */
- r6040_free_rxbufs(dev);
-
- /* Free TX buffer */
- r6040_free_txbufs(dev);
-
- /* Free Descriptor memory */
- pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma);
- pci_free_consistent(pdev, TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma);
}
static int r6040_close(struct net_device *dev)
{
struct r6040_private *lp = netdev_priv(dev);
+ struct pci_dev *pdev = lp->pdev;
/* deleted timer */
del_timer_sync(&lp->timer);
@@ -481,8 +471,28 @@ static int r6040_close(struct net_device *dev)
napi_disable(&lp->napi);
netif_stop_queue(dev);
r6040_down(dev);
+
+ free_irq(dev->irq, dev);
+
+ /* Free RX buffer */
+ r6040_free_rxbufs(dev);
+
+ /* Free TX buffer */
+ r6040_free_txbufs(dev);
+
spin_unlock_irq(&lp->lock);
+ /* Free Descriptor memory */
+ if (lp->rx_ring) {
+ pci_free_consistent(pdev, RX_DESC_SIZE, lp->rx_ring, lp->rx_ring_dma);
+ lp->rx_ring = 0;
+ }
+
+ if (lp->tx_ring) {
+ pci_free_consistent(pdev, TX_DESC_SIZE, lp->tx_ring, lp->tx_ring_dma);
+ lp->tx_ring = 0;
+ }
+
return 0;
}
@@ -1049,6 +1059,7 @@ static const struct net_device_ops r6040_netdev_ops = {
.ndo_set_multicast_list = r6040_multicast_list,
.ndo_change_mtu = eth_change_mtu,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_do_ioctl = r6040_ioctl,
.ndo_tx_timeout = r6040_tx_timeout,
#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -1143,8 +1154,10 @@ static int __devinit r6040_init_one(struct pci_dev *pdev,
/* Some bootloader/BIOSes do not initialize
* MAC address, warn about that */
- if (!(adrp[0] || adrp[1] || adrp[2]))
- printk(KERN_WARNING DRV_NAME ": MAC address not initialized\n");
+ if (!(adrp[0] || adrp[1] || adrp[2])) {
+ printk(KERN_WARNING DRV_NAME ": MAC address not initialized, generating random\n");
+ random_ether_addr(dev->dev_addr);
+ }
/* Link new device into r6040_root_dev */
lp->pdev = pdev;
diff --git a/drivers/net/sc92031.c b/drivers/net/sc92031.c
index 42fd312..8b75bef 100644
--- a/drivers/net/sc92031.c
+++ b/drivers/net/sc92031.c
@@ -1408,6 +1408,7 @@ static const struct net_device_ops sc92031_netdev_ops = {
.ndo_set_multicast_list = sc92031_set_multicast_list,
.ndo_change_mtu = eth_change_mtu,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_tx_timeout = sc92031_tx_timeout,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = sc92031_poll_controller,
diff --git a/drivers/net/sfc/efx.c b/drivers/net/sfc/efx.c
index 7673fd9..101c00a 100644
--- a/drivers/net/sfc/efx.c
+++ b/drivers/net/sfc/efx.c
@@ -854,20 +854,27 @@ static void efx_fini_io(struct efx_nic *efx)
* interrupts across them. */
static int efx_wanted_rx_queues(void)
{
- cpumask_t core_mask;
+ cpumask_var_t core_mask;
int count;
int cpu;
- cpus_clear(core_mask);
+ if (!alloc_cpumask_var(&core_mask, GFP_KERNEL)) {
+ printk(KERN_WARNING
+ "efx.c: allocation failure, irq balancing hobbled\n");
+ return 1;
+ }
+
+ cpumask_clear(core_mask);
count = 0;
for_each_online_cpu(cpu) {
- if (!cpu_isset(cpu, core_mask)) {
+ if (!cpumask_test_cpu(cpu, core_mask)) {
++count;
- cpus_or(core_mask, core_mask,
- topology_core_siblings(cpu));
+ cpumask_or(core_mask, core_mask,
+ topology_core_cpumask(cpu));
}
}
+ free_cpumask_var(core_mask);
return count;
}
diff --git a/drivers/net/sfc/tenxpress.c b/drivers/net/sfc/tenxpress.c
index b976876..9ecb77d 100644
--- a/drivers/net/sfc/tenxpress.c
+++ b/drivers/net/sfc/tenxpress.c
@@ -636,10 +636,11 @@ static void tenxpress_phy_fini(struct efx_nic *efx)
{
int reg;
- if (efx->phy_type == PHY_TYPE_SFT9001B) {
+ if (efx->phy_type == PHY_TYPE_SFT9001B)
device_remove_file(&efx->pci_dev->dev,
&dev_attr_phy_short_reach);
- } else {
+
+ if (efx->phy_type == PHY_TYPE_SFX7101) {
/* Power down the LNPGA */
reg = (1 << PMA_PMD_LNPGA_POWERDOWN_LBN);
mdio_clause45_write(efx, efx->mii.phy_id, MDIO_MMD_PMAPMD,
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 4acd41a..6cbefca 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -389,6 +389,7 @@ static const struct net_device_ops sis900_netdev_ops = {
.ndo_set_multicast_list = set_rx_mode,
.ndo_change_mtu = eth_change_mtu,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_do_ioctl = mii_ioctl,
.ndo_tx_timeout = sis900_tx_timeout,
#ifdef CONFIG_NET_POLL_CONTROLLER
diff --git a/drivers/net/smc-mca.c b/drivers/net/smc-mca.c
index 404b80e..8d36d40 100644
--- a/drivers/net/smc-mca.c
+++ b/drivers/net/smc-mca.c
@@ -192,6 +192,7 @@ static const struct net_device_ops ultramca_netdev_ops = {
.ndo_get_stats = ei_get_stats,
.ndo_set_multicast_list = ei_set_multicast_list,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ei_poll,
diff --git a/drivers/net/smc-ultra.c b/drivers/net/smc-ultra.c
index b386608..2033fee 100644
--- a/drivers/net/smc-ultra.c
+++ b/drivers/net/smc-ultra.c
@@ -196,6 +196,7 @@ static const struct net_device_ops ultra_netdev_ops = {
.ndo_get_stats = ei_get_stats,
.ndo_set_multicast_list = ei_set_multicast_list,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ei_poll,
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index dc3f110..f513bdf 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -144,6 +144,7 @@ static inline u32 smsc911x_reg_read(struct smsc911x_data *pdata, u32 reg)
}
BUG();
+ return 0;
}
static inline void smsc911x_reg_write(struct smsc911x_data *pdata, u32 reg,
@@ -1740,6 +1741,7 @@ static const struct net_device_ops smsc911x_netdev_ops = {
.ndo_set_multicast_list = smsc911x_set_multicast_list,
.ndo_do_ioctl = smsc911x_do_ioctl,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = smsc911x_poll_controller,
#endif
@@ -1967,7 +1969,7 @@ static int __devinit smsc911x_drv_probe(struct platform_device *pdev)
smsc911x_reg_write(pdata, INT_STS, 0xFFFFFFFF);
retval = request_irq(dev->irq, smsc911x_irqhandler, IRQF_DISABLED,
- SMSC_CHIPNAME, dev);
+ dev->name, dev);
if (retval) {
SMSC_WARNING(PROBE,
"Unable to claim requested irq: %d", dev->irq);
diff --git a/drivers/net/smsc9420.c b/drivers/net/smsc9420.c
index 27e017d..c14a4c6 100644
--- a/drivers/net/smsc9420.c
+++ b/drivers/net/smsc9420.c
@@ -1551,6 +1551,7 @@ static const struct net_device_ops smsc9420_netdev_ops = {
.ndo_set_multicast_list = smsc9420_set_multicast_list,
.ndo_do_ioctl = smsc9420_do_ioctl,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = smsc9420_poll_controller,
#endif /* CONFIG_NET_POLL_CONTROLLER */
diff --git a/drivers/net/ucc_geth.c b/drivers/net/ucc_geth.c
index 7d5a130..1144122 100644
--- a/drivers/net/ucc_geth.c
+++ b/drivers/net/ucc_geth.c
@@ -442,40 +442,30 @@ static void magic_packet_detection_enable(struct ucc_geth_private *ugeth)
{
struct ucc_fast_private *uccf;
struct ucc_geth __iomem *ug_regs;
- u32 maccfg2, uccm;
uccf = ugeth->uccf;
ug_regs = ugeth->ug_regs;
/* Enable interrupts for magic packet detection */
- uccm = in_be32(uccf->p_uccm);
- uccm |= UCCE_MPD;
- out_be32(uccf->p_uccm, uccm);
+ setbits32(uccf->p_uccm, UCC_GETH_UCCE_MPD);
/* Enable magic packet detection */
- maccfg2 = in_be32(&ug_regs->maccfg2);
- maccfg2 |= MACCFG2_MPE;
- out_be32(&ug_regs->maccfg2, maccfg2);
+ setbits32(&ug_regs->maccfg2, MACCFG2_MPE);
}
static void magic_packet_detection_disable(struct ucc_geth_private *ugeth)
{
struct ucc_fast_private *uccf;
struct ucc_geth __iomem *ug_regs;
- u32 maccfg2, uccm;
uccf = ugeth->uccf;
ug_regs = ugeth->ug_regs;
/* Disable interrupts for magic packet detection */
- uccm = in_be32(uccf->p_uccm);
- uccm &= ~UCCE_MPD;
- out_be32(uccf->p_uccm, uccm);
+ clrbits32(uccf->p_uccm, UCC_GETH_UCCE_MPD);
/* Disable magic packet detection */
- maccfg2 = in_be32(&ug_regs->maccfg2);
- maccfg2 &= ~MACCFG2_MPE;
- out_be32(&ug_regs->maccfg2, maccfg2);
+ clrbits32(&ug_regs->maccfg2, MACCFG2_MPE);
}
#endif /* MAGIC_PACKET */
@@ -585,7 +575,8 @@ static void get_statistics(struct ucc_geth_private *ugeth,
/* Hardware only if user handed pointer and driver actually
gathers hardware statistics */
- if (hardware_statistics && (in_be32(&uf_regs->upsmr) & UPSMR_HSE)) {
+ if (hardware_statistics &&
+ (in_be32(&uf_regs->upsmr) & UCC_GETH_UPSMR_HSE)) {
hardware_statistics->tx64 = in_be32(&ug_regs->tx64);
hardware_statistics->tx127 = in_be32(&ug_regs->tx127);
hardware_statistics->tx255 = in_be32(&ug_regs->tx255);
@@ -1181,9 +1172,7 @@ int init_flow_control_params(u32 automatic_flow_control_mode,
out_be32(uempr_register, value);
/* Set UPSMR register */
- value = in_be32(upsmr_register);
- value |= automatic_flow_control_mode;
- out_be32(upsmr_register, value);
+ setbits32(upsmr_register, automatic_flow_control_mode);
value = in_be32(maccfg1_register);
if (rx_flow_control_enable)
@@ -1200,14 +1189,11 @@ static int init_hw_statistics_gathering_mode(int enable_hardware_statistics,
u32 __iomem *upsmr_register,
u16 __iomem *uescr_register)
{
- u32 upsmr_value = 0;
u16 uescr_value = 0;
+
/* Enable hardware statistics gathering if requested */
- if (enable_hardware_statistics) {
- upsmr_value = in_be32(upsmr_register);
- upsmr_value |= UPSMR_HSE;
- out_be32(upsmr_register, upsmr_value);
- }
+ if (enable_hardware_statistics)
+ setbits32(upsmr_register, UCC_GETH_UPSMR_HSE);
/* Clear hardware statistics counters */
uescr_value = in_be16(uescr_register);
@@ -1233,23 +1219,17 @@ static int init_firmware_statistics_gathering_mode(int
{
/* Note: this function does not check if */
/* the parameters it receives are NULL */
- u16 temoder_value;
- u32 remoder_value;
if (enable_tx_firmware_statistics) {
out_be32(tx_rmon_base_ptr,
tx_firmware_statistics_structure_address);
- temoder_value = in_be16(temoder_register);
- temoder_value |= TEMODER_TX_RMON_STATISTICS_ENABLE;
- out_be16(temoder_register, temoder_value);
+ setbits16(temoder_register, TEMODER_TX_RMON_STATISTICS_ENABLE);
}
if (enable_rx_firmware_statistics) {
out_be32(rx_rmon_base_ptr,
rx_firmware_statistics_structure_address);
- remoder_value = in_be32(remoder_register);
- remoder_value |= REMODER_RX_RMON_STATISTICS_ENABLE;
- out_be32(remoder_register, remoder_value);
+ setbits32(remoder_register, REMODER_RX_RMON_STATISTICS_ENABLE);
}
return 0;
@@ -1316,15 +1296,12 @@ static int init_check_frame_length_mode(int length_check,
static int init_preamble_length(u8 preamble_length,
u32 __iomem *maccfg2_register)
{
- u32 value = 0;
-
if ((preamble_length < 3) || (preamble_length > 7))
return -EINVAL;
- value = in_be32(maccfg2_register);
- value &= ~MACCFG2_PREL_MASK;
- value |= (preamble_length << MACCFG2_PREL_SHIFT);
- out_be32(maccfg2_register, value);
+ clrsetbits_be32(maccfg2_register, MACCFG2_PREL_MASK,
+ preamble_length << MACCFG2_PREL_SHIFT);
+
return 0;
}
@@ -1337,19 +1314,19 @@ static int init_rx_parameters(int reject_broadcast,
value = in_be32(upsmr_register);
if (reject_broadcast)
- value |= UPSMR_BRO;
+ value |= UCC_GETH_UPSMR_BRO;
else
- value &= ~UPSMR_BRO;
+ value &= ~UCC_GETH_UPSMR_BRO;
if (receive_short_frames)
- value |= UPSMR_RSH;
+ value |= UCC_GETH_UPSMR_RSH;
else
- value &= ~UPSMR_RSH;
+ value &= ~UCC_GETH_UPSMR_RSH;
if (promiscuous)
- value |= UPSMR_PRO;
+ value |= UCC_GETH_UPSMR_PRO;
else
- value &= ~UPSMR_PRO;
+ value &= ~UCC_GETH_UPSMR_PRO;
out_be32(upsmr_register, value);
@@ -1410,26 +1387,27 @@ static int adjust_enet_interface(struct ucc_geth_private *ugeth)
/* Set UPSMR */
upsmr = in_be32(&uf_regs->upsmr);
- upsmr &= ~(UPSMR_RPM | UPSMR_R10M | UPSMR_TBIM | UPSMR_RMM);
+ upsmr &= ~(UCC_GETH_UPSMR_RPM | UCC_GETH_UPSMR_R10M |
+ UCC_GETH_UPSMR_TBIM | UCC_GETH_UPSMR_RMM);
if ((ugeth->phy_interface == PHY_INTERFACE_MODE_RMII) ||
(ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII) ||
(ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_ID) ||
(ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_RXID) ||
(ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
(ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
- upsmr |= UPSMR_RPM;
+ upsmr |= UCC_GETH_UPSMR_RPM;
switch (ugeth->max_speed) {
case SPEED_10:
- upsmr |= UPSMR_R10M;
+ upsmr |= UCC_GETH_UPSMR_R10M;
/* FALLTHROUGH */
case SPEED_100:
if (ugeth->phy_interface != PHY_INTERFACE_MODE_RTBI)
- upsmr |= UPSMR_RMM;
+ upsmr |= UCC_GETH_UPSMR_RMM;
}
}
if ((ugeth->phy_interface == PHY_INTERFACE_MODE_TBI) ||
(ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
- upsmr |= UPSMR_TBIM;
+ upsmr |= UCC_GETH_UPSMR_TBIM;
}
out_be32(&uf_regs->upsmr, upsmr);
@@ -1517,9 +1495,9 @@ static void adjust_link(struct net_device *dev)
(ugeth->phy_interface == PHY_INTERFACE_MODE_RGMII_TXID) ||
(ugeth->phy_interface == PHY_INTERFACE_MODE_RTBI)) {
if (phydev->speed == SPEED_10)
- upsmr |= UPSMR_R10M;
+ upsmr |= UCC_GETH_UPSMR_R10M;
else
- upsmr &= ~(UPSMR_R10M);
+ upsmr &= ~UCC_GETH_UPSMR_R10M;
}
break;
default:
@@ -1602,10 +1580,8 @@ static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth)
uccf = ugeth->uccf;
/* Mask GRACEFUL STOP TX interrupt bit and clear it */
- temp = in_be32(uccf->p_uccm);
- temp &= ~UCCE_GRA;
- out_be32(uccf->p_uccm, temp);
- out_be32(uccf->p_ucce, UCCE_GRA); /* clear by writing 1 */
+ clrbits32(uccf->p_uccm, UCC_GETH_UCCE_GRA);
+ out_be32(uccf->p_ucce, UCC_GETH_UCCE_GRA); /* clear by writing 1 */
/* Issue host command */
cecr_subblock =
@@ -1617,7 +1593,7 @@ static int ugeth_graceful_stop_tx(struct ucc_geth_private *ugeth)
do {
msleep(10);
temp = in_be32(uccf->p_ucce);
- } while (!(temp & UCCE_GRA) && --i);
+ } while (!(temp & UCC_GETH_UCCE_GRA) && --i);
uccf->stopped_tx = 1;
@@ -1975,12 +1951,9 @@ static void ucc_geth_set_multi(struct net_device *dev)
uf_regs = ugeth->uccf->uf_regs;
if (dev->flags & IFF_PROMISC) {
-
- out_be32(&uf_regs->upsmr, in_be32(&uf_regs->upsmr) | UPSMR_PRO);
-
+ setbits32(&uf_regs->upsmr, UCC_GETH_UPSMR_PRO);
} else {
-
- out_be32(&uf_regs->upsmr, in_be32(&uf_regs->upsmr)&~UPSMR_PRO);
+ clrbits32(&uf_regs->upsmr, UCC_GETH_UPSMR_PRO);
p_82xx_addr_filt =
(struct ucc_geth_82xx_address_filtering_pram __iomem *) ugeth->
@@ -2020,7 +1993,6 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
{
struct ucc_geth __iomem *ug_regs = ugeth->ug_regs;
struct phy_device *phydev = ugeth->phydev;
- u32 tempval;
ugeth_vdbg("%s: IN", __func__);
@@ -2037,9 +2009,7 @@ static void ucc_geth_stop(struct ucc_geth_private *ugeth)
out_be32(ugeth->uccf->p_ucce, 0xffffffff);
/* Disable Rx and Tx */
- tempval = in_be32(&ug_regs->maccfg1);
- tempval &= ~(MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX);
- out_be32(&ug_regs->maccfg1, tempval);
+ clrbits32(&ug_regs->maccfg1, MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX);
ucc_geth_memclean(ugeth);
}
@@ -2153,10 +2123,10 @@ static int ucc_struct_init(struct ucc_geth_private *ugeth)
/* Generate uccm_mask for receive */
uf_info->uccm_mask = ug_info->eventRegMask & UCCE_OTHER;/* Errors */
for (i = 0; i < ug_info->numQueuesRx; i++)
- uf_info->uccm_mask |= (UCCE_RXBF_SINGLE_MASK << i);
+ uf_info->uccm_mask |= (UCC_GETH_UCCE_RXF0 << i);
for (i = 0; i < ug_info->numQueuesTx; i++)
- uf_info->uccm_mask |= (UCCE_TXBF_SINGLE_MASK << i);
+ uf_info->uccm_mask |= (UCC_GETH_UCCE_TXB0 << i);
/* Initialize the general fast UCC block. */
if (ucc_fast_init(uf_info, &ugeth->uccf)) {
if (netif_msg_probe(ugeth))
@@ -2185,7 +2155,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
struct ucc_geth __iomem *ug_regs;
int ret_val = -EINVAL;
u32 remoder = UCC_GETH_REMODER_INIT;
- u32 init_enet_pram_offset, cecr_subblock, command, maccfg1;
+ u32 init_enet_pram_offset, cecr_subblock, command;
u32 ifstat, i, j, size, l2qt, l3qt, length;
u16 temoder = UCC_GETH_TEMODER_INIT;
u16 test;
@@ -2281,10 +2251,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth)
&uf_regs->upsmr,
&ug_regs->uempr, &ug_regs->maccfg1);
- maccfg1 = in_be32(&ug_regs->maccfg1);
- maccfg1 |= MACCFG1_ENABLE_RX;
- maccfg1 |= MACCFG1_ENABLE_TX;
- out_be32(&ug_regs->maccfg1, maccfg1);
+ setbits32(&ug_regs->maccfg1, MACCFG1_ENABLE_RX | MACCFG1_ENABLE_TX);
/* Set IPGIFG */
/* For more details see the hardware spec. */
@@ -3274,7 +3241,6 @@ static int ucc_geth_tx(struct net_device *dev, u8 txQ)
static int ucc_geth_poll(struct napi_struct *napi, int budget)
{
struct ucc_geth_private *ugeth = container_of(napi, struct ucc_geth_private, napi);
- struct net_device *dev = ugeth->dev;
struct ucc_geth_info *ug_info;
int howmany, i;
@@ -3285,14 +3251,8 @@ static int ucc_geth_poll(struct napi_struct *napi, int budget)
howmany += ucc_geth_rx(ugeth, i, budget - howmany);
if (howmany < budget) {
- struct ucc_fast_private *uccf;
- u32 uccm;
-
netif_rx_complete(napi);
- uccf = ugeth->uccf;
- uccm = in_be32(uccf->p_uccm);
- uccm |= UCCE_RX_EVENTS;
- out_be32(uccf->p_uccm, uccm);
+ setbits32(ugeth->uccf->p_uccm, UCCE_RX_EVENTS);
}
return howmany;
@@ -3332,7 +3292,7 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
/* Tx event processing */
if (ucce & UCCE_TX_EVENTS) {
spin_lock(&ugeth->lock);
- tx_mask = UCCE_TXBF_SINGLE_MASK;
+ tx_mask = UCC_GETH_UCCE_TXB0;
for (i = 0; i < ug_info->numQueuesTx; i++) {
if (ucce & tx_mask)
ucc_geth_tx(dev, i);
@@ -3344,12 +3304,10 @@ static irqreturn_t ucc_geth_irq_handler(int irq, void *info)
/* Errors and other events */
if (ucce & UCCE_OTHER) {
- if (ucce & UCCE_BSY) {
+ if (ucce & UCC_GETH_UCCE_BSY)
dev->stats.rx_errors++;
- }
- if (ucce & UCCE_TXE) {
+ if (ucce & UCC_GETH_UCCE_TXE)
dev->stats.tx_errors++;
- }
}
return IRQ_HANDLED;
diff --git a/drivers/net/ucc_geth.h b/drivers/net/ucc_geth.h
index d74d2f7..8f699cb 100644
--- a/drivers/net/ucc_geth.h
+++ b/drivers/net/ucc_geth.h
@@ -162,92 +162,27 @@ struct ucc_geth {
boundary */
/* UCC GETH Event Register */
-#define UCCE_MPD 0x80000000 /* Magic packet
- detection */
-#define UCCE_SCAR 0x40000000
-#define UCCE_GRA 0x20000000 /* Tx graceful
- stop
- complete */
-#define UCCE_CBPR 0x10000000
-#define UCCE_BSY 0x08000000
-#define UCCE_RXC 0x04000000
-#define UCCE_TXC 0x02000000
-#define UCCE_TXE 0x01000000
-#define UCCE_TXB7 0x00800000
-#define UCCE_TXB6 0x00400000
-#define UCCE_TXB5 0x00200000
-#define UCCE_TXB4 0x00100000
-#define UCCE_TXB3 0x00080000
-#define UCCE_TXB2 0x00040000
-#define UCCE_TXB1 0x00020000
-#define UCCE_TXB0 0x00010000
-#define UCCE_RXB7 0x00008000
-#define UCCE_RXB6 0x00004000
-#define UCCE_RXB5 0x00002000
-#define UCCE_RXB4 0x00001000
-#define UCCE_RXB3 0x00000800
-#define UCCE_RXB2 0x00000400
-#define UCCE_RXB1 0x00000200
-#define UCCE_RXB0 0x00000100
-#define UCCE_RXF7 0x00000080
-#define UCCE_RXF6 0x00000040
-#define UCCE_RXF5 0x00000020
-#define UCCE_RXF4 0x00000010
-#define UCCE_RXF3 0x00000008
-#define UCCE_RXF2 0x00000004
-#define UCCE_RXF1 0x00000002
-#define UCCE_RXF0 0x00000001
-
-#define UCCE_RXBF_SINGLE_MASK (UCCE_RXF0)
-#define UCCE_TXBF_SINGLE_MASK (UCCE_TXB0)
-
-#define UCCE_TXB (UCCE_TXB7 | UCCE_TXB6 | UCCE_TXB5 | UCCE_TXB4 |\
- UCCE_TXB3 | UCCE_TXB2 | UCCE_TXB1 | UCCE_TXB0)
-#define UCCE_RXB (UCCE_RXB7 | UCCE_RXB6 | UCCE_RXB5 | UCCE_RXB4 |\
- UCCE_RXB3 | UCCE_RXB2 | UCCE_RXB1 | UCCE_RXB0)
-#define UCCE_RXF (UCCE_RXF7 | UCCE_RXF6 | UCCE_RXF5 | UCCE_RXF4 |\
- UCCE_RXF3 | UCCE_RXF2 | UCCE_RXF1 | UCCE_RXF0)
-#define UCCE_OTHER (UCCE_SCAR | UCCE_GRA | UCCE_CBPR | UCCE_BSY |\
- UCCE_RXC | UCCE_TXC | UCCE_TXE)
-
-#define UCCE_RX_EVENTS (UCCE_RXF | UCCE_BSY)
-#define UCCE_TX_EVENTS (UCCE_TXB | UCCE_TXE)
-
-/* UCC GETH UPSMR (Protocol Specific Mode Register) */
-#define UPSMR_ECM 0x04000000 /* Enable CAM
- Miss or
- Enable
- Filtering
- Miss */
-#define UPSMR_HSE 0x02000000 /* Hardware
- Statistics
- Enable */
-#define UPSMR_PRO 0x00400000 /* Promiscuous*/
-#define UPSMR_CAP 0x00200000 /* CAM polarity
- */
-#define UPSMR_RSH 0x00100000 /* Receive
- Short Frames
- */
-#define UPSMR_RPM 0x00080000 /* Reduced Pin
- Mode
- interfaces */
-#define UPSMR_R10M 0x00040000 /* RGMII/RMII
- 10 Mode */
-#define UPSMR_RLPB 0x00020000 /* RMII
- Loopback
- Mode */
-#define UPSMR_TBIM 0x00010000 /* Ten-bit
- Interface
- Mode */
-#define UPSMR_RMM 0x00001000 /* RMII/RGMII
- Mode */
-#define UPSMR_CAM 0x00000400 /* CAM Address
- Matching */
-#define UPSMR_BRO 0x00000200 /* Broadcast
- Address */
-#define UPSMR_RES1 0x00002000 /* Reserved
- feild - must
- be 1 */
+#define UCCE_TXB (UCC_GETH_UCCE_TXB7 | UCC_GETH_UCCE_TXB6 | \
+ UCC_GETH_UCCE_TXB5 | UCC_GETH_UCCE_TXB4 | \
+ UCC_GETH_UCCE_TXB3 | UCC_GETH_UCCE_TXB2 | \
+ UCC_GETH_UCCE_TXB1 | UCC_GETH_UCCE_TXB0)
+
+#define UCCE_RXB (UCC_GETH_UCCE_RXB7 | UCC_GETH_UCCE_RXB6 | \
+ UCC_GETH_UCCE_RXB5 | UCC_GETH_UCCE_RXB4 | \
+ UCC_GETH_UCCE_RXB3 | UCC_GETH_UCCE_RXB2 | \
+ UCC_GETH_UCCE_RXB1 | UCC_GETH_UCCE_RXB0)
+
+#define UCCE_RXF (UCC_GETH_UCCE_RXF7 | UCC_GETH_UCCE_RXF6 | \
+ UCC_GETH_UCCE_RXF5 | UCC_GETH_UCCE_RXF4 | \
+ UCC_GETH_UCCE_RXF3 | UCC_GETH_UCCE_RXF2 | \
+ UCC_GETH_UCCE_RXF1 | UCC_GETH_UCCE_RXF0)
+
+#define UCCE_OTHER (UCC_GETH_UCCE_SCAR | UCC_GETH_UCCE_GRA | \
+ UCC_GETH_UCCE_CBPR | UCC_GETH_UCCE_BSY | \
+ UCC_GETH_UCCE_RXC | UCC_GETH_UCCE_TXC | UCC_GETH_UCCE_TXE)
+
+#define UCCE_RX_EVENTS (UCCE_RXF | UCC_GETH_UCCE_BSY)
+#define UCCE_TX_EVENTS (UCCE_TXB | UCC_GETH_UCCE_TXE)
/* UCC GETH MACCFG1 (MAC Configuration 1 Register) */
#define MACCFG1_FLOW_RX 0x00000020 /* Flow Control
@@ -945,9 +880,10 @@ struct ucc_geth_hardware_statistics {
#define UCC_GETH_REMODER_INIT 0 /* bits that must be
set */
#define UCC_GETH_TEMODER_INIT 0xC000 /* bits that must */
-#define UCC_GETH_UPSMR_INIT (UPSMR_RES1) /* Start value
- for this
- register */
+
+/* Initial value for UPSMR */
+#define UCC_GETH_UPSMR_INIT UCC_GETH_UPSMR_RES1
+
#define UCC_GETH_MACCFG1_INIT 0
#define UCC_GETH_MACCFG2_INIT (MACCFG2_RESERVED_1)
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index ac07cc6..3b8e632 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -622,6 +622,7 @@ static const struct net_device_ops rhine_netdev_ops = {
.ndo_get_stats = rhine_get_stats,
.ndo_set_multicast_list = rhine_set_rx_mode,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_do_ioctl = netdev_ioctl,
.ndo_tx_timeout = rhine_tx_timeout,
#ifdef CONFIG_NET_POLL_CONTROLLER
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index 58e25d0..a75f91d 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -855,6 +855,7 @@ static const struct net_device_ops velocity_netdev_ops = {
.ndo_start_xmit = velocity_xmit,
.ndo_get_stats = velocity_get_stats,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_set_multicast_list = velocity_set_multi,
.ndo_change_mtu = velocity_change_mtu,
.ndo_do_ioctl = velocity_ioctl,
diff --git a/drivers/net/wd.c b/drivers/net/wd.c
index 3c1edda..d8322d2 100644
--- a/drivers/net/wd.c
+++ b/drivers/net/wd.c
@@ -155,6 +155,7 @@ static const struct net_device_ops wd_netdev_ops = {
.ndo_get_stats = ei_get_stats,
.ndo_set_multicast_list = ei_set_multicast_list,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ei_poll,
diff --git a/drivers/net/wireless/libertas/main.c b/drivers/net/wireless/libertas/main.c
index 3dba836..4e0007d 100644
--- a/drivers/net/wireless/libertas/main.c
+++ b/drivers/net/wireless/libertas/main.c
@@ -1369,7 +1369,7 @@ EXPORT_SYMBOL_GPL(lbs_start_card);
void lbs_stop_card(struct lbs_private *priv)
{
- struct net_device *dev = priv->dev;
+ struct net_device *dev;
struct cmd_ctrl_node *cmdnode;
unsigned long flags;
@@ -1377,9 +1377,10 @@ void lbs_stop_card(struct lbs_private *priv)
if (!priv)
goto out;
+ dev = priv->dev;
- netif_stop_queue(priv->dev);
- netif_carrier_off(priv->dev);
+ netif_stop_queue(dev);
+ netif_carrier_off(dev);
lbs_debugfs_remove_one(priv);
if (priv->mesh_tlv) {
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index cf97129..2f1645d 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -362,6 +362,7 @@ static const struct net_device_ops netdev_ops = {
.ndo_set_multicast_list = set_rx_mode,
.ndo_change_mtu = eth_change_mtu,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_do_ioctl = netdev_ioctl,
.ndo_tx_timeout = yellowfin_tx_timeout,
};
diff --git a/drivers/net/zorro8390.c b/drivers/net/zorro8390.c
index affd904..37c84e3 100644
--- a/drivers/net/zorro8390.c
+++ b/drivers/net/zorro8390.c
@@ -147,6 +147,7 @@ static const struct net_device_ops zorro8390_netdev_ops = {
.ndo_get_stats = ei_get_stats,
.ndo_set_multicast_list = ei_set_multicast_list,
.ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
.ndo_change_mtu = eth_change_mtu,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = ei_poll,
diff --git a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
index 9da5a4b..c3ea5fa 100644
--- a/drivers/oprofile/buffer_sync.c
+++ b/drivers/oprofile/buffer_sync.c
@@ -38,7 +38,7 @@
static LIST_HEAD(dying_tasks);
static LIST_HEAD(dead_tasks);
-static cpumask_t marked_cpus = CPU_MASK_NONE;
+static cpumask_var_t marked_cpus;
static DEFINE_SPINLOCK(task_mortuary);
static void process_task_mortuary(void);
@@ -456,10 +456,10 @@ static void mark_done(int cpu)
{
int i;
- cpu_set(cpu, marked_cpus);
+ cpumask_set_cpu(cpu, marked_cpus);
for_each_online_cpu(i) {
- if (!cpu_isset(i, marked_cpus))
+ if (!cpumask_test_cpu(i, marked_cpus))
return;
}
@@ -468,7 +468,7 @@ static void mark_done(int cpu)
*/
process_task_mortuary();
- cpus_clear(marked_cpus);
+ cpumask_clear(marked_cpus);
}
@@ -565,6 +565,20 @@ void sync_buffer(int cpu)
mutex_unlock(&buffer_mutex);
}
+int __init buffer_sync_init(void)
+{
+ if (!alloc_cpumask_var(&marked_cpus, GFP_KERNEL))
+ return -ENOMEM;
+
+ cpumask_clear(marked_cpus);
+ return 0;
+}
+
+void __exit buffer_sync_cleanup(void)
+{
+ free_cpumask_var(marked_cpus);
+}
+
/* The function can be used to add a buffer worth of data directly to
* the kernel buffer. The buffer is assumed to be a circular buffer.
* Take the entries from index start and end at index end, wrapping
diff --git a/drivers/oprofile/buffer_sync.h b/drivers/oprofile/buffer_sync.h
index 3110732..0ebf5db 100644
--- a/drivers/oprofile/buffer_sync.h
+++ b/drivers/oprofile/buffer_sync.h
@@ -19,4 +19,8 @@ void sync_stop(void);
/* sync the given CPU's buffer */
void sync_buffer(int cpu);
+/* initialize/destroy the buffer system. */
+int buffer_sync_init(void);
+void buffer_sync_cleanup(void);
+
#endif /* OPROFILE_BUFFER_SYNC_H */
diff --git a/drivers/oprofile/oprof.c b/drivers/oprofile/oprof.c
index 3cffce9..ced39f6 100644
--- a/drivers/oprofile/oprof.c
+++ b/drivers/oprofile/oprof.c
@@ -183,6 +183,10 @@ static int __init oprofile_init(void)
{
int err;
+ err = buffer_sync_init();
+ if (err)
+ return err;
+
err = oprofile_arch_init(&oprofile_ops);
if (err < 0 || timer) {
@@ -191,8 +195,10 @@ static int __init oprofile_init(void)
}
err = oprofilefs_register();
- if (err)
+ if (err) {
oprofile_arch_exit();
+ buffer_sync_cleanup();
+ }
return err;
}
@@ -202,6 +208,7 @@ static void __exit oprofile_exit(void)
{
oprofilefs_unregister();
oprofile_arch_exit();
+ buffer_sync_cleanup();
}
diff --git a/drivers/parisc/superio.c b/drivers/parisc/superio.c
index 1e93c83..4fa3bb2 100644
--- a/drivers/parisc/superio.c
+++ b/drivers/parisc/superio.c
@@ -405,7 +405,6 @@ static void __init superio_serial_init(void)
serial_port.type = PORT_16550A;
serial_port.uartclk = 115200*16;
serial_port.fifosize = 16;
- spin_lock_init(&serial_port.lock);
/* serial port #1 */
serial_port.iobase = sio_dev.sp1_base;
diff --git a/drivers/pci/intel-iommu.c b/drivers/pci/intel-iommu.c
index 235fb7a..3dfecb2 100644
--- a/drivers/pci/intel-iommu.c
+++ b/drivers/pci/intel-iommu.c
@@ -438,7 +438,8 @@ static struct intel_iommu *device_to_iommu(u8 bus, u8 devfn)
continue;
for (i = 0; i < drhd->devices_cnt; i++)
- if (drhd->devices[i]->bus->number == bus &&
+ if (drhd->devices[i] &&
+ drhd->devices[i]->bus->number == bus &&
drhd->devices[i]->devfn == devfn)
return drhd->iommu;
diff --git a/drivers/pci/intr_remapping.c b/drivers/pci/intr_remapping.c
index f78371b..5a57753 100644
--- a/drivers/pci/intr_remapping.c
+++ b/drivers/pci/intr_remapping.c
@@ -6,6 +6,7 @@
#include <linux/irq.h>
#include <asm/io_apic.h>
#include <asm/smp.h>
+#include <asm/cpu.h>
#include <linux/intel-iommu.h>
#include "intr_remapping.h"
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 6684724..33da112 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -82,4 +82,10 @@ config BATTERY_DA9030
Say Y here to enable support for batteries charger integrated into
DA9030 PMIC.
+config CHARGER_PCF50633
+ tristate "NXP PCF50633 MBC"
+ depends on MFD_PCF50633
+ help
+ Say Y to include support for NXP PCF50633 Main Battery Charger.
+
endif # POWER_SUPPLY
diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index eebb155..2fcf41d 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -25,3 +25,4 @@ obj-$(CONFIG_BATTERY_TOSA) += tosa_battery.o
obj-$(CONFIG_BATTERY_WM97XX) += wm97xx_battery.o
obj-$(CONFIG_BATTERY_BQ27x00) += bq27x00_battery.o
obj-$(CONFIG_BATTERY_DA9030) += da9030_battery.o
+obj-$(CONFIG_CHARGER_PCF50633) += pcf50633-charger.o \ No newline at end of file
diff --git a/drivers/power/pcf50633-charger.c b/drivers/power/pcf50633-charger.c
new file mode 100644
index 0000000..e988ec1
--- /dev/null
+++ b/drivers/power/pcf50633-charger.c
@@ -0,0 +1,358 @@
+/* NXP PCF50633 Main Battery Charger Driver
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * Author: Balaji Rao <balajirrao@openmoko.org>
+ * All rights reserved.
+ *
+ * Broken down from monstrous PCF50633 driver mainly by
+ * Harald Welte, Andy Green and Werner Almesberger
+ *
+ * This program is free software; you can redistribute 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/module.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/sysfs.h>
+#include <linux/platform_device.h>
+#include <linux/power_supply.h>
+
+#include <linux/mfd/pcf50633/core.h>
+#include <linux/mfd/pcf50633/mbc.h>
+
+struct pcf50633_mbc {
+ struct pcf50633 *pcf;
+
+ int adapter_active;
+ int adapter_online;
+ int usb_active;
+ int usb_online;
+
+ struct power_supply usb;
+ struct power_supply adapter;
+};
+
+int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma)
+{
+ struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev);
+ int ret = 0;
+ u8 bits;
+
+ if (ma >= 1000)
+ bits = PCF50633_MBCC7_USB_1000mA;
+ else if (ma >= 500)
+ bits = PCF50633_MBCC7_USB_500mA;
+ else if (ma >= 100)
+ bits = PCF50633_MBCC7_USB_100mA;
+ else
+ bits = PCF50633_MBCC7_USB_SUSPEND;
+
+ ret = pcf50633_reg_set_bit_mask(pcf, PCF50633_REG_MBCC7,
+ PCF50633_MBCC7_USB_MASK, bits);
+ if (ret)
+ dev_err(pcf->dev, "error setting usb curlim to %d mA\n", ma);
+ else
+ dev_info(pcf->dev, "usb curlim to %d mA\n", ma);
+
+ power_supply_changed(&mbc->usb);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pcf50633_mbc_usb_curlim_set);
+
+int pcf50633_mbc_get_status(struct pcf50633 *pcf)
+{
+ struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev);
+ int status = 0;
+
+ if (mbc->usb_online)
+ status |= PCF50633_MBC_USB_ONLINE;
+ if (mbc->usb_active)
+ status |= PCF50633_MBC_USB_ACTIVE;
+ if (mbc->adapter_online)
+ status |= PCF50633_MBC_ADAPTER_ONLINE;
+ if (mbc->adapter_active)
+ status |= PCF50633_MBC_ADAPTER_ACTIVE;
+
+ return status;
+}
+EXPORT_SYMBOL_GPL(pcf50633_mbc_get_status);
+
+void pcf50633_mbc_set_status(struct pcf50633 *pcf, int what, int status)
+{
+ struct pcf50633_mbc *mbc = platform_get_drvdata(pcf->mbc_pdev);
+
+ if (what & PCF50633_MBC_USB_ONLINE)
+ mbc->usb_online = !!status;
+ if (what & PCF50633_MBC_USB_ACTIVE)
+ mbc->usb_active = !!status;
+ if (what & PCF50633_MBC_ADAPTER_ONLINE)
+ mbc->adapter_online = !!status;
+ if (what & PCF50633_MBC_ADAPTER_ACTIVE)
+ mbc->adapter_active = !!status;
+}
+EXPORT_SYMBOL_GPL(pcf50633_mbc_set_status);
+
+static ssize_t
+show_chgmode(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct pcf50633_mbc *mbc = dev_get_drvdata(dev);
+
+ u8 mbcs2 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCS2);
+ u8 chgmod = (mbcs2 & PCF50633_MBCS2_MBC_MASK);
+
+ return sprintf(buf, "%d\n", chgmod);
+}
+static DEVICE_ATTR(chgmode, S_IRUGO, show_chgmode, NULL);
+
+static ssize_t
+show_usblim(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct pcf50633_mbc *mbc = dev_get_drvdata(dev);
+ u8 usblim = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCC7) &
+ PCF50633_MBCC7_USB_MASK;
+ unsigned int ma;
+
+ if (usblim == PCF50633_MBCC7_USB_1000mA)
+ ma = 1000;
+ else if (usblim == PCF50633_MBCC7_USB_500mA)
+ ma = 500;
+ else if (usblim == PCF50633_MBCC7_USB_100mA)
+ ma = 100;
+ else
+ ma = 0;
+
+ return sprintf(buf, "%u\n", ma);
+}
+
+static ssize_t set_usblim(struct device *dev,
+ struct device_attribute *attr, const char *buf, size_t count)
+{
+ struct pcf50633_mbc *mbc = dev_get_drvdata(dev);
+ unsigned long ma;
+ int ret;
+
+ ret = strict_strtoul(buf, 10, &ma);
+ if (ret)
+ return -EINVAL;
+
+ pcf50633_mbc_usb_curlim_set(mbc->pcf, ma);
+
+ return count;
+}
+
+static DEVICE_ATTR(usb_curlim, S_IRUGO | S_IWUSR, show_usblim, set_usblim);
+
+static struct attribute *pcf50633_mbc_sysfs_entries[] = {
+ &dev_attr_chgmode.attr,
+ &dev_attr_usb_curlim.attr,
+ NULL,
+};
+
+static struct attribute_group mbc_attr_group = {
+ .name = NULL, /* put in device directory */
+ .attrs = pcf50633_mbc_sysfs_entries,
+};
+
+static void
+pcf50633_mbc_irq_handler(int irq, void *data)
+{
+ struct pcf50633_mbc *mbc = data;
+
+ /* USB */
+ if (irq == PCF50633_IRQ_USBINS) {
+ mbc->usb_online = 1;
+ } else if (irq == PCF50633_IRQ_USBREM) {
+ mbc->usb_online = 0;
+ mbc->usb_active = 0;
+ pcf50633_mbc_usb_curlim_set(mbc->pcf, 0);
+ }
+
+ /* Adapter */
+ if (irq == PCF50633_IRQ_ADPINS) {
+ mbc->adapter_online = 1;
+ mbc->adapter_active = 1;
+ } else if (irq == PCF50633_IRQ_ADPREM) {
+ mbc->adapter_online = 0;
+ mbc->adapter_active = 0;
+ }
+
+ if (irq == PCF50633_IRQ_BATFULL) {
+ mbc->usb_active = 0;
+ mbc->adapter_active = 0;
+ }
+
+ power_supply_changed(&mbc->usb);
+ power_supply_changed(&mbc->adapter);
+
+ if (mbc->pcf->pdata->mbc_event_callback)
+ mbc->pcf->pdata->mbc_event_callback(mbc->pcf, irq);
+}
+
+static int adapter_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, usb);
+ int ret = 0;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = mbc->adapter_online;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static int usb_get_property(struct power_supply *psy,
+ enum power_supply_property psp,
+ union power_supply_propval *val)
+{
+ struct pcf50633_mbc *mbc = container_of(psy, struct pcf50633_mbc, usb);
+ int ret = 0;
+
+ switch (psp) {
+ case POWER_SUPPLY_PROP_ONLINE:
+ val->intval = mbc->usb_online;
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ return ret;
+}
+
+static enum power_supply_property power_props[] = {
+ POWER_SUPPLY_PROP_ONLINE,
+};
+
+static const u8 mbc_irq_handlers[] = {
+ PCF50633_IRQ_ADPINS,
+ PCF50633_IRQ_ADPREM,
+ PCF50633_IRQ_USBINS,
+ PCF50633_IRQ_USBREM,
+ PCF50633_IRQ_BATFULL,
+ PCF50633_IRQ_CHGHALT,
+ PCF50633_IRQ_THLIMON,
+ PCF50633_IRQ_THLIMOFF,
+ PCF50633_IRQ_USBLIMON,
+ PCF50633_IRQ_USBLIMOFF,
+ PCF50633_IRQ_LOWSYS,
+ PCF50633_IRQ_LOWBAT,
+};
+
+static int __devinit pcf50633_mbc_probe(struct platform_device *pdev)
+{
+ struct pcf50633_mbc *mbc;
+ struct pcf50633_subdev_pdata *pdata = pdev->dev.platform_data;
+ int ret;
+ int i;
+ u8 mbcs1;
+
+ mbc = kzalloc(sizeof(*mbc), GFP_KERNEL);
+ if (!mbc)
+ return -ENOMEM;
+
+ platform_set_drvdata(pdev, mbc);
+ mbc->pcf = pdata->pcf;
+
+ /* Set up IRQ handlers */
+ for (i = 0; i < ARRAY_SIZE(mbc_irq_handlers); i++)
+ pcf50633_register_irq(mbc->pcf, mbc_irq_handlers[i],
+ pcf50633_mbc_irq_handler, mbc);
+
+ /* Create power supplies */
+ mbc->adapter.name = "adapter";
+ mbc->adapter.type = POWER_SUPPLY_TYPE_MAINS;
+ mbc->adapter.properties = power_props;
+ mbc->adapter.num_properties = ARRAY_SIZE(power_props);
+ mbc->adapter.get_property = &adapter_get_property;
+ mbc->adapter.supplied_to = mbc->pcf->pdata->batteries;
+ mbc->adapter.num_supplicants = mbc->pcf->pdata->num_batteries;
+
+ mbc->usb.name = "usb";
+ mbc->usb.type = POWER_SUPPLY_TYPE_USB;
+ mbc->usb.properties = power_props;
+ mbc->usb.num_properties = ARRAY_SIZE(power_props);
+ mbc->usb.get_property = usb_get_property;
+ mbc->usb.supplied_to = mbc->pcf->pdata->batteries;
+ mbc->usb.num_supplicants = mbc->pcf->pdata->num_batteries;
+
+ ret = power_supply_register(&pdev->dev, &mbc->adapter);
+ if (ret) {
+ dev_err(mbc->pcf->dev, "failed to register adapter\n");
+ kfree(mbc);
+ return ret;
+ }
+
+ ret = power_supply_register(&pdev->dev, &mbc->usb);
+ if (ret) {
+ dev_err(mbc->pcf->dev, "failed to register usb\n");
+ power_supply_unregister(&mbc->adapter);
+ kfree(mbc);
+ return ret;
+ }
+
+ ret = sysfs_create_group(&pdev->dev.kobj, &mbc_attr_group);
+ if (ret)
+ dev_err(mbc->pcf->dev, "failed to create sysfs entries\n");
+
+ mbcs1 = pcf50633_reg_read(mbc->pcf, PCF50633_REG_MBCS1);
+ if (mbcs1 & PCF50633_MBCS1_USBPRES)
+ pcf50633_mbc_irq_handler(PCF50633_IRQ_USBINS, mbc);
+ if (mbcs1 & PCF50633_MBCS1_ADAPTPRES)
+ pcf50633_mbc_irq_handler(PCF50633_IRQ_ADPINS, mbc);
+
+ return 0;
+}
+
+static int __devexit pcf50633_mbc_remove(struct platform_device *pdev)
+{
+ struct pcf50633_mbc *mbc = platform_get_drvdata(pdev);
+ int i;
+
+ /* Remove IRQ handlers */
+ for (i = 0; i < ARRAY_SIZE(mbc_irq_handlers); i++)
+ pcf50633_free_irq(mbc->pcf, mbc_irq_handlers[i]);
+
+ power_supply_unregister(&mbc->usb);
+ power_supply_unregister(&mbc->adapter);
+
+ kfree(mbc);
+
+ return 0;
+}
+
+static struct platform_driver pcf50633_mbc_driver = {
+ .driver = {
+ .name = "pcf50633-mbc",
+ },
+ .probe = pcf50633_mbc_probe,
+ .remove = __devexit_p(pcf50633_mbc_remove),
+};
+
+static int __init pcf50633_mbc_init(void)
+{
+ return platform_driver_register(&pcf50633_mbc_driver);
+}
+module_init(pcf50633_mbc_init);
+
+static void __exit pcf50633_mbc_exit(void)
+{
+ platform_driver_unregister(&pcf50633_mbc_driver);
+}
+module_exit(pcf50633_mbc_exit);
+
+MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
+MODULE_DESCRIPTION("PCF50633 mbc driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pcf50633-mbc");
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index 39360e2..e7e0cf1 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -73,4 +73,11 @@ config REGULATOR_DA903X
Say y here to support the BUCKs and LDOs regulators found on
Dialog Semiconductor DA9030/DA9034 PMIC.
+config REGULATOR_PCF50633
+ tristate "PCF50633 regulator driver"
+ depends on MFD_PCF50633
+ help
+ Say Y here to support the voltage regulators and convertors
+ on PCF50633
+
endif
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile
index 254d40c..61b30c6 100644
--- a/drivers/regulator/Makefile
+++ b/drivers/regulator/Makefile
@@ -11,5 +11,6 @@ obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
+obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
diff --git a/drivers/regulator/pcf50633-regulator.c b/drivers/regulator/pcf50633-regulator.c
new file mode 100644
index 0000000..4cc85ec
--- /dev/null
+++ b/drivers/regulator/pcf50633-regulator.c
@@ -0,0 +1,329 @@
+/* NXP PCF50633 PMIC Driver
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * Author: Balaji Rao <balajirrao@openmoko.org>
+ * All rights reserved.
+ *
+ * Broken down from monstrous PCF50633 driver mainly by
+ * Harald Welte and Andy Green and Werner Almesberger
+ *
+ * This program is free software; you can redistribute 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/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+
+#include <linux/mfd/pcf50633/core.h>
+#include <linux/mfd/pcf50633/pmic.h>
+
+#define PCF50633_REGULATOR(_name, _id) \
+ { \
+ .name = _name, \
+ .id = _id, \
+ .ops = &pcf50633_regulator_ops, \
+ .type = REGULATOR_VOLTAGE, \
+ .owner = THIS_MODULE, \
+ }
+
+static const u8 pcf50633_regulator_registers[PCF50633_NUM_REGULATORS] = {
+ [PCF50633_REGULATOR_AUTO] = PCF50633_REG_AUTOOUT,
+ [PCF50633_REGULATOR_DOWN1] = PCF50633_REG_DOWN1OUT,
+ [PCF50633_REGULATOR_DOWN2] = PCF50633_REG_DOWN2OUT,
+ [PCF50633_REGULATOR_MEMLDO] = PCF50633_REG_MEMLDOOUT,
+ [PCF50633_REGULATOR_LDO1] = PCF50633_REG_LDO1OUT,
+ [PCF50633_REGULATOR_LDO2] = PCF50633_REG_LDO2OUT,
+ [PCF50633_REGULATOR_LDO3] = PCF50633_REG_LDO3OUT,
+ [PCF50633_REGULATOR_LDO4] = PCF50633_REG_LDO4OUT,
+ [PCF50633_REGULATOR_LDO5] = PCF50633_REG_LDO5OUT,
+ [PCF50633_REGULATOR_LDO6] = PCF50633_REG_LDO6OUT,
+ [PCF50633_REGULATOR_HCLDO] = PCF50633_REG_HCLDOOUT,
+};
+
+/* Bits from voltage value */
+static u8 auto_voltage_bits(unsigned int millivolts)
+{
+ if (millivolts < 1800)
+ return 0;
+ if (millivolts > 3800)
+ return 0xff;
+
+ millivolts -= 625;
+
+ return millivolts / 25;
+}
+
+static u8 down_voltage_bits(unsigned int millivolts)
+{
+ if (millivolts < 625)
+ return 0;
+ else if (millivolts > 3000)
+ return 0xff;
+
+ millivolts -= 625;
+
+ return millivolts / 25;
+}
+
+static u8 ldo_voltage_bits(unsigned int millivolts)
+{
+ if (millivolts < 900)
+ return 0;
+ else if (millivolts > 3600)
+ return 0x1f;
+
+ millivolts -= 900;
+ return millivolts / 100;
+}
+
+/* Obtain voltage value from bits */
+static unsigned int auto_voltage_value(u8 bits)
+{
+ if (bits < 0x2f)
+ return 0;
+
+ return 625 + (bits * 25);
+}
+
+
+static unsigned int down_voltage_value(u8 bits)
+{
+ return 625 + (bits * 25);
+}
+
+
+static unsigned int ldo_voltage_value(u8 bits)
+{
+ bits &= 0x1f;
+
+ return 900 + (bits * 100);
+}
+
+static int pcf50633_regulator_set_voltage(struct regulator_dev *rdev,
+ int min_uV, int max_uV)
+{
+ struct pcf50633 *pcf;
+ int regulator_id, millivolts;
+ u8 volt_bits, regnr;
+
+ pcf = rdev_get_drvdata(rdev);
+
+ regulator_id = rdev_get_id(rdev);
+ if (regulator_id >= PCF50633_NUM_REGULATORS)
+ return -EINVAL;
+
+ millivolts = min_uV / 1000;
+
+ regnr = pcf50633_regulator_registers[regulator_id];
+
+ switch (regulator_id) {
+ case PCF50633_REGULATOR_AUTO:
+ volt_bits = auto_voltage_bits(millivolts);
+ break;
+ case PCF50633_REGULATOR_DOWN1:
+ volt_bits = down_voltage_bits(millivolts);
+ break;
+ case PCF50633_REGULATOR_DOWN2:
+ volt_bits = down_voltage_bits(millivolts);
+ break;
+ case PCF50633_REGULATOR_LDO1:
+ case PCF50633_REGULATOR_LDO2:
+ case PCF50633_REGULATOR_LDO3:
+ case PCF50633_REGULATOR_LDO4:
+ case PCF50633_REGULATOR_LDO5:
+ case PCF50633_REGULATOR_LDO6:
+ case PCF50633_REGULATOR_HCLDO:
+ volt_bits = ldo_voltage_bits(millivolts);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return pcf50633_reg_write(pcf, regnr, volt_bits);
+}
+
+static int pcf50633_regulator_get_voltage(struct regulator_dev *rdev)
+{
+ struct pcf50633 *pcf;
+ int regulator_id, millivolts, volt_bits;
+ u8 regnr;
+
+ pcf = rdev_get_drvdata(rdev);;
+
+ regulator_id = rdev_get_id(rdev);
+ if (regulator_id >= PCF50633_NUM_REGULATORS)
+ return -EINVAL;
+
+ regnr = pcf50633_regulator_registers[regulator_id];
+
+ volt_bits = pcf50633_reg_read(pcf, regnr);
+ if (volt_bits < 0)
+ return -1;
+
+ switch (regulator_id) {
+ case PCF50633_REGULATOR_AUTO:
+ millivolts = auto_voltage_value(volt_bits);
+ break;
+ case PCF50633_REGULATOR_DOWN1:
+ millivolts = down_voltage_value(volt_bits);
+ break;
+ case PCF50633_REGULATOR_DOWN2:
+ millivolts = down_voltage_value(volt_bits);
+ break;
+ case PCF50633_REGULATOR_LDO1:
+ case PCF50633_REGULATOR_LDO2:
+ case PCF50633_REGULATOR_LDO3:
+ case PCF50633_REGULATOR_LDO4:
+ case PCF50633_REGULATOR_LDO5:
+ case PCF50633_REGULATOR_LDO6:
+ case PCF50633_REGULATOR_HCLDO:
+ millivolts = ldo_voltage_value(volt_bits);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ return millivolts * 1000;
+}
+
+static int pcf50633_regulator_enable(struct regulator_dev *rdev)
+{
+ struct pcf50633 *pcf = rdev_get_drvdata(rdev);
+ int regulator_id;
+ u8 regnr;
+
+ regulator_id = rdev_get_id(rdev);
+ if (regulator_id >= PCF50633_NUM_REGULATORS)
+ return -EINVAL;
+
+ /* The *ENA register is always one after the *OUT register */
+ regnr = pcf50633_regulator_registers[regulator_id] + 1;
+
+ return pcf50633_reg_set_bit_mask(pcf, regnr, PCF50633_REGULATOR_ON,
+ PCF50633_REGULATOR_ON);
+}
+
+static int pcf50633_regulator_disable(struct regulator_dev *rdev)
+{
+ struct pcf50633 *pcf = rdev_get_drvdata(rdev);
+ int regulator_id;
+ u8 regnr;
+
+ regulator_id = rdev_get_id(rdev);
+ if (regulator_id >= PCF50633_NUM_REGULATORS)
+ return -EINVAL;
+
+ /* the *ENA register is always one after the *OUT register */
+ regnr = pcf50633_regulator_registers[regulator_id] + 1;
+
+ return pcf50633_reg_set_bit_mask(pcf, regnr,
+ PCF50633_REGULATOR_ON, 0);
+}
+
+static int pcf50633_regulator_is_enabled(struct regulator_dev *rdev)
+{
+ struct pcf50633 *pcf = rdev_get_drvdata(rdev);
+ int regulator_id = rdev_get_id(rdev);
+ u8 regnr;
+
+ regulator_id = rdev_get_id(rdev);
+ if (regulator_id >= PCF50633_NUM_REGULATORS)
+ return -EINVAL;
+
+ /* the *ENA register is always one after the *OUT register */
+ regnr = pcf50633_regulator_registers[regulator_id] + 1;
+
+ return pcf50633_reg_read(pcf, regnr) & PCF50633_REGULATOR_ON;
+}
+
+static struct regulator_ops pcf50633_regulator_ops = {
+ .set_voltage = pcf50633_regulator_set_voltage,
+ .get_voltage = pcf50633_regulator_get_voltage,
+ .enable = pcf50633_regulator_enable,
+ .disable = pcf50633_regulator_disable,
+ .is_enabled = pcf50633_regulator_is_enabled,
+};
+
+static struct regulator_desc regulators[] = {
+ [PCF50633_REGULATOR_AUTO] =
+ PCF50633_REGULATOR("auto", PCF50633_REGULATOR_AUTO),
+ [PCF50633_REGULATOR_DOWN1] =
+ PCF50633_REGULATOR("down1", PCF50633_REGULATOR_DOWN1),
+ [PCF50633_REGULATOR_DOWN2] =
+ PCF50633_REGULATOR("down2", PCF50633_REGULATOR_DOWN2),
+ [PCF50633_REGULATOR_LDO1] =
+ PCF50633_REGULATOR("ldo1", PCF50633_REGULATOR_LDO1),
+ [PCF50633_REGULATOR_LDO2] =
+ PCF50633_REGULATOR("ldo2", PCF50633_REGULATOR_LDO2),
+ [PCF50633_REGULATOR_LDO3] =
+ PCF50633_REGULATOR("ldo3", PCF50633_REGULATOR_LDO3),
+ [PCF50633_REGULATOR_LDO4] =
+ PCF50633_REGULATOR("ldo4", PCF50633_REGULATOR_LDO4),
+ [PCF50633_REGULATOR_LDO5] =
+ PCF50633_REGULATOR("ldo5", PCF50633_REGULATOR_LDO5),
+ [PCF50633_REGULATOR_LDO6] =
+ PCF50633_REGULATOR("ldo6", PCF50633_REGULATOR_LDO6),
+ [PCF50633_REGULATOR_HCLDO] =
+ PCF50633_REGULATOR("hcldo", PCF50633_REGULATOR_HCLDO),
+ [PCF50633_REGULATOR_MEMLDO] =
+ PCF50633_REGULATOR("memldo", PCF50633_REGULATOR_MEMLDO),
+};
+
+static int __devinit pcf50633_regulator_probe(struct platform_device *pdev)
+{
+ struct regulator_dev *rdev;
+ struct pcf50633 *pcf;
+
+ /* Already set by core driver */
+ pcf = platform_get_drvdata(pdev);
+
+ rdev = regulator_register(&regulators[pdev->id], &pdev->dev, pcf);
+ if (IS_ERR(rdev))
+ return PTR_ERR(rdev);
+
+ if (pcf->pdata->regulator_registered)
+ pcf->pdata->regulator_registered(pcf, pdev->id);
+
+ return 0;
+}
+
+static int __devexit pcf50633_regulator_remove(struct platform_device *pdev)
+{
+ struct regulator_dev *rdev = platform_get_drvdata(pdev);
+
+ regulator_unregister(rdev);
+
+ return 0;
+}
+
+static struct platform_driver pcf50633_regulator_driver = {
+ .driver = {
+ .name = "pcf50633-regltr",
+ },
+ .probe = pcf50633_regulator_probe,
+ .remove = __devexit_p(pcf50633_regulator_remove),
+};
+
+static int __init pcf50633_regulator_init(void)
+{
+ return platform_driver_register(&pcf50633_regulator_driver);
+}
+module_init(pcf50633_regulator_init);
+
+static void __exit pcf50633_regulator_exit(void)
+{
+ platform_driver_unregister(&pcf50633_regulator_driver);
+}
+module_exit(pcf50633_regulator_exit);
+
+MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
+MODULE_DESCRIPTION("PCF50633 regulator driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:pcf50633-regulator");
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index 4ad831d..cced4d1 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -502,6 +502,13 @@ config RTC_DRV_WM8350
This driver can also be built as a module. If so, the module
will be called "rtc-wm8350".
+config RTC_DRV_PCF50633
+ depends on MFD_PCF50633
+ tristate "NXP PCF50633 RTC"
+ help
+ If you say yes here you get support for the RTC subsystem of the
+ NXP PCF50633 used in embedded systems.
+
comment "on-CPU RTC drivers"
config RTC_DRV_OMAP
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index 9a4340d..6e28021 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -74,3 +74,4 @@ obj-$(CONFIG_RTC_DRV_V3020) += rtc-v3020.o
obj-$(CONFIG_RTC_DRV_VR41XX) += rtc-vr41xx.o
obj-$(CONFIG_RTC_DRV_WM8350) += rtc-wm8350.o
obj-$(CONFIG_RTC_DRV_X1205) += rtc-x1205.o
+obj-$(CONFIG_RTC_DRV_PCF50633) += rtc-pcf50633.o
diff --git a/drivers/rtc/rtc-pcf50633.c b/drivers/rtc/rtc-pcf50633.c
new file mode 100644
index 0000000..f4dd87e
--- /dev/null
+++ b/drivers/rtc/rtc-pcf50633.c
@@ -0,0 +1,344 @@
+/* NXP PCF50633 RTC Driver
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * Author: Balaji Rao <balajirrao@openmoko.org>
+ * All rights reserved.
+ *
+ * Broken down from monstrous PCF50633 driver mainly by
+ * Harald Welte, Andy Green and Werner Almesberger
+ *
+ * This program is free software; you can redistribute 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/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/rtc.h>
+#include <linux/bcd.h>
+#include <linux/err.h>
+
+#include <linux/mfd/pcf50633/core.h>
+
+#define PCF50633_REG_RTCSC 0x59 /* Second */
+#define PCF50633_REG_RTCMN 0x5a /* Minute */
+#define PCF50633_REG_RTCHR 0x5b /* Hour */
+#define PCF50633_REG_RTCWD 0x5c /* Weekday */
+#define PCF50633_REG_RTCDT 0x5d /* Day */
+#define PCF50633_REG_RTCMT 0x5e /* Month */
+#define PCF50633_REG_RTCYR 0x5f /* Year */
+#define PCF50633_REG_RTCSCA 0x60 /* Alarm Second */
+#define PCF50633_REG_RTCMNA 0x61 /* Alarm Minute */
+#define PCF50633_REG_RTCHRA 0x62 /* Alarm Hour */
+#define PCF50633_REG_RTCWDA 0x63 /* Alarm Weekday */
+#define PCF50633_REG_RTCDTA 0x64 /* Alarm Day */
+#define PCF50633_REG_RTCMTA 0x65 /* Alarm Month */
+#define PCF50633_REG_RTCYRA 0x66 /* Alarm Year */
+
+enum pcf50633_time_indexes {
+ PCF50633_TI_SEC,
+ PCF50633_TI_MIN,
+ PCF50633_TI_HOUR,
+ PCF50633_TI_WKDAY,
+ PCF50633_TI_DAY,
+ PCF50633_TI_MONTH,
+ PCF50633_TI_YEAR,
+ PCF50633_TI_EXTENT /* always last */
+};
+
+struct pcf50633_time {
+ u_int8_t time[PCF50633_TI_EXTENT];
+};
+
+struct pcf50633_rtc {
+ int alarm_enabled;
+ int second_enabled;
+
+ struct pcf50633 *pcf;
+ struct rtc_device *rtc_dev;
+};
+
+static void pcf2rtc_time(struct rtc_time *rtc, struct pcf50633_time *pcf)
+{
+ rtc->tm_sec = bcd2bin(pcf->time[PCF50633_TI_SEC]);
+ rtc->tm_min = bcd2bin(pcf->time[PCF50633_TI_MIN]);
+ rtc->tm_hour = bcd2bin(pcf->time[PCF50633_TI_HOUR]);
+ rtc->tm_wday = bcd2bin(pcf->time[PCF50633_TI_WKDAY]);
+ rtc->tm_mday = bcd2bin(pcf->time[PCF50633_TI_DAY]);
+ rtc->tm_mon = bcd2bin(pcf->time[PCF50633_TI_MONTH]);
+ rtc->tm_year = bcd2bin(pcf->time[PCF50633_TI_YEAR]) + 100;
+}
+
+static void rtc2pcf_time(struct pcf50633_time *pcf, struct rtc_time *rtc)
+{
+ pcf->time[PCF50633_TI_SEC] = bin2bcd(rtc->tm_sec);
+ pcf->time[PCF50633_TI_MIN] = bin2bcd(rtc->tm_min);
+ pcf->time[PCF50633_TI_HOUR] = bin2bcd(rtc->tm_hour);
+ pcf->time[PCF50633_TI_WKDAY] = bin2bcd(rtc->tm_wday);
+ pcf->time[PCF50633_TI_DAY] = bin2bcd(rtc->tm_mday);
+ pcf->time[PCF50633_TI_MONTH] = bin2bcd(rtc->tm_mon);
+ pcf->time[PCF50633_TI_YEAR] = bin2bcd(rtc->tm_year % 100);
+}
+
+static int
+pcf50633_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled)
+{
+ struct pcf50633_rtc *rtc = dev_get_drvdata(dev);
+ int err;
+
+ if (enabled)
+ err = pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM);
+ else
+ err = pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_ALARM);
+
+ if (err < 0)
+ return err;
+
+ rtc->alarm_enabled = enabled;
+
+ return 0;
+}
+
+static int
+pcf50633_rtc_update_irq_enable(struct device *dev, unsigned int enabled)
+{
+ struct pcf50633_rtc *rtc = dev_get_drvdata(dev);
+ int err;
+
+ if (enabled)
+ err = pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_SECOND);
+ else
+ err = pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_SECOND);
+
+ if (err < 0)
+ return err;
+
+ rtc->second_enabled = enabled;
+
+ return 0;
+}
+
+static int pcf50633_rtc_read_time(struct device *dev, struct rtc_time *tm)
+{
+ struct pcf50633_rtc *rtc;
+ struct pcf50633_time pcf_tm;
+ int ret;
+
+ rtc = dev_get_drvdata(dev);
+
+ ret = pcf50633_read_block(rtc->pcf, PCF50633_REG_RTCSC,
+ PCF50633_TI_EXTENT,
+ &pcf_tm.time[0]);
+ if (ret != PCF50633_TI_EXTENT) {
+ dev_err(dev, "Failed to read time\n");
+ return -EIO;
+ }
+
+ dev_dbg(dev, "PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n",
+ pcf_tm.time[PCF50633_TI_DAY],
+ pcf_tm.time[PCF50633_TI_MONTH],
+ pcf_tm.time[PCF50633_TI_YEAR],
+ pcf_tm.time[PCF50633_TI_HOUR],
+ pcf_tm.time[PCF50633_TI_MIN],
+ pcf_tm.time[PCF50633_TI_SEC]);
+
+ pcf2rtc_time(tm, &pcf_tm);
+
+ dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n",
+ tm->tm_mday, tm->tm_mon, tm->tm_year,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+ return rtc_valid_tm(tm);
+}
+
+static int pcf50633_rtc_set_time(struct device *dev, struct rtc_time *tm)
+{
+ struct pcf50633_rtc *rtc;
+ struct pcf50633_time pcf_tm;
+ int second_masked, alarm_masked, ret = 0;
+
+ rtc = dev_get_drvdata(dev);
+
+ dev_dbg(dev, "RTC_TIME: %u.%u.%u %u:%u:%u\n",
+ tm->tm_mday, tm->tm_mon, tm->tm_year,
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+
+ rtc2pcf_time(&pcf_tm, tm);
+
+ dev_dbg(dev, "PCF_TIME: %02x.%02x.%02x %02x:%02x:%02x\n",
+ pcf_tm.time[PCF50633_TI_DAY],
+ pcf_tm.time[PCF50633_TI_MONTH],
+ pcf_tm.time[PCF50633_TI_YEAR],
+ pcf_tm.time[PCF50633_TI_HOUR],
+ pcf_tm.time[PCF50633_TI_MIN],
+ pcf_tm.time[PCF50633_TI_SEC]);
+
+
+ second_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_SECOND);
+ alarm_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_ALARM);
+
+ if (!second_masked)
+ pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_SECOND);
+ if (!alarm_masked)
+ pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_ALARM);
+
+ /* Returns 0 on success */
+ ret = pcf50633_write_block(rtc->pcf, PCF50633_REG_RTCSC,
+ PCF50633_TI_EXTENT,
+ &pcf_tm.time[0]);
+
+ if (!second_masked)
+ pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_SECOND);
+ if (!alarm_masked)
+ pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM);
+
+ return ret;
+}
+
+static int pcf50633_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct pcf50633_rtc *rtc;
+ struct pcf50633_time pcf_tm;
+ int ret = 0;
+
+ rtc = dev_get_drvdata(dev);
+
+ alrm->enabled = rtc->alarm_enabled;
+
+ ret = pcf50633_read_block(rtc->pcf, PCF50633_REG_RTCSCA,
+ PCF50633_TI_EXTENT, &pcf_tm.time[0]);
+ if (ret != PCF50633_TI_EXTENT) {
+ dev_err(dev, "Failed to read time\n");
+ return -EIO;
+ }
+
+ pcf2rtc_time(&alrm->time, &pcf_tm);
+
+ return rtc_valid_tm(&alrm->time);
+}
+
+static int pcf50633_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm)
+{
+ struct pcf50633_rtc *rtc;
+ struct pcf50633_time pcf_tm;
+ int alarm_masked, ret = 0;
+
+ rtc = dev_get_drvdata(dev);
+
+ rtc2pcf_time(&pcf_tm, &alrm->time);
+
+ /* do like mktime does and ignore tm_wday */
+ pcf_tm.time[PCF50633_TI_WKDAY] = 7;
+
+ alarm_masked = pcf50633_irq_mask_get(rtc->pcf, PCF50633_IRQ_ALARM);
+
+ /* disable alarm interrupt */
+ if (!alarm_masked)
+ pcf50633_irq_mask(rtc->pcf, PCF50633_IRQ_ALARM);
+
+ /* Returns 0 on success */
+ ret = pcf50633_write_block(rtc->pcf, PCF50633_REG_RTCSCA,
+ PCF50633_TI_EXTENT, &pcf_tm.time[0]);
+
+ if (!alarm_masked)
+ pcf50633_irq_unmask(rtc->pcf, PCF50633_IRQ_ALARM);
+
+ return ret;
+}
+
+static struct rtc_class_ops pcf50633_rtc_ops = {
+ .read_time = pcf50633_rtc_read_time,
+ .set_time = pcf50633_rtc_set_time,
+ .read_alarm = pcf50633_rtc_read_alarm,
+ .set_alarm = pcf50633_rtc_set_alarm,
+ .alarm_irq_enable = pcf50633_rtc_alarm_irq_enable,
+ .update_irq_enable = pcf50633_rtc_update_irq_enable,
+};
+
+static void pcf50633_rtc_irq(int irq, void *data)
+{
+ struct pcf50633_rtc *rtc = data;
+
+ switch (irq) {
+ case PCF50633_IRQ_ALARM:
+ rtc_update_irq(rtc->rtc_dev, 1, RTC_AF | RTC_IRQF);
+ break;
+ case PCF50633_IRQ_SECOND:
+ rtc_update_irq(rtc->rtc_dev, 1, RTC_UF | RTC_IRQF);
+ break;
+ }
+}
+
+static int __devinit pcf50633_rtc_probe(struct platform_device *pdev)
+{
+ struct pcf50633_subdev_pdata *pdata;
+ struct pcf50633_rtc *rtc;
+
+
+ rtc = kzalloc(sizeof(*rtc), GFP_KERNEL);
+ if (!rtc)
+ return -ENOMEM;
+
+ pdata = pdev->dev.platform_data;
+ rtc->pcf = pdata->pcf;
+ platform_set_drvdata(pdev, rtc);
+ rtc->rtc_dev = rtc_device_register("pcf50633-rtc", &pdev->dev,
+ &pcf50633_rtc_ops, THIS_MODULE);
+
+ if (IS_ERR(rtc->rtc_dev)) {
+ kfree(rtc);
+ return PTR_ERR(rtc->rtc_dev);
+ }
+
+ pcf50633_register_irq(rtc->pcf, PCF50633_IRQ_ALARM,
+ pcf50633_rtc_irq, rtc);
+ pcf50633_register_irq(rtc->pcf, PCF50633_IRQ_SECOND,
+ pcf50633_rtc_irq, rtc);
+
+ return 0;
+}
+
+static int __devexit pcf50633_rtc_remove(struct platform_device *pdev)
+{
+ struct pcf50633_rtc *rtc;
+
+ rtc = platform_get_drvdata(pdev);
+
+ pcf50633_free_irq(rtc->pcf, PCF50633_IRQ_ALARM);
+ pcf50633_free_irq(rtc->pcf, PCF50633_IRQ_SECOND);
+
+ rtc_device_unregister(rtc->rtc_dev);
+ kfree(rtc);
+
+ return 0;
+}
+
+static struct platform_driver pcf50633_rtc_driver = {
+ .driver = {
+ .name = "pcf50633-rtc",
+ },
+ .probe = pcf50633_rtc_probe,
+ .remove = __devexit_p(pcf50633_rtc_remove),
+};
+
+static int __init pcf50633_rtc_init(void)
+{
+ return platform_driver_register(&pcf50633_rtc_driver);
+}
+module_init(pcf50633_rtc_init);
+
+static void __exit pcf50633_rtc_exit(void)
+{
+ platform_driver_unregister(&pcf50633_rtc_driver);
+}
+module_exit(pcf50633_rtc_exit);
+
+MODULE_DESCRIPTION("PCF50633 RTC driver");
+MODULE_AUTHOR("Balaji Rao <balajirrao@openmoko.org>");
+MODULE_LICENSE("GPL");
+
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index c4f1b04..07ab8a5 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -916,7 +916,7 @@ static struct ethtool_ops qeth_l2_osn_ops = {
.get_drvinfo = qeth_core_get_drvinfo,
};
-static struct net_device_ops qeth_l2_netdev_ops = {
+static const struct net_device_ops qeth_l2_netdev_ops = {
.ndo_open = qeth_l2_open,
.ndo_stop = qeth_l2_stop,
.ndo_get_stats = qeth_get_stats,
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 68d623a..3d04920 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -2894,7 +2894,7 @@ qeth_l3_neigh_setup(struct net_device *dev, struct neigh_parms *np)
return 0;
}
-static struct net_device_ops qeth_l3_netdev_ops = {
+static const struct net_device_ops qeth_l3_netdev_ops = {
.ndo_open = qeth_l3_open,
.ndo_stop = qeth_l3_stop,
.ndo_get_stats = qeth_get_stats,
@@ -2909,6 +2909,22 @@ static struct net_device_ops qeth_l3_netdev_ops = {
.ndo_tx_timeout = qeth_tx_timeout,
};
+static const struct net_device_ops qeth_l3_osa_netdev_ops = {
+ .ndo_open = qeth_l3_open,
+ .ndo_stop = qeth_l3_stop,
+ .ndo_get_stats = qeth_get_stats,
+ .ndo_start_xmit = qeth_l3_hard_start_xmit,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_multicast_list = qeth_l3_set_multicast_list,
+ .ndo_do_ioctl = qeth_l3_do_ioctl,
+ .ndo_change_mtu = qeth_change_mtu,
+ .ndo_vlan_rx_register = qeth_l3_vlan_rx_register,
+ .ndo_vlan_rx_add_vid = qeth_l3_vlan_rx_add_vid,
+ .ndo_vlan_rx_kill_vid = qeth_l3_vlan_rx_kill_vid,
+ .ndo_tx_timeout = qeth_tx_timeout,
+ .ndo_neigh_setup = qeth_l3_neigh_setup,
+};
+
static int qeth_l3_setup_netdev(struct qeth_card *card)
{
if (card->info.type == QETH_CARD_TYPE_OSAE) {
@@ -2919,12 +2935,12 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
#endif
if (!card->dev)
return -ENODEV;
+ card->dev->netdev_ops = &qeth_l3_netdev_ops;
} else {
card->dev = alloc_etherdev(0);
if (!card->dev)
return -ENODEV;
- qeth_l3_netdev_ops.ndo_neigh_setup =
- qeth_l3_neigh_setup;
+ card->dev->netdev_ops = &qeth_l3_osa_netdev_ops;
/*IPv6 address autoconfiguration stuff*/
qeth_l3_get_unique_id(card);
@@ -2937,6 +2953,7 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
if (!card->dev)
return -ENODEV;
card->dev->flags |= IFF_NOARP;
+ card->dev->netdev_ops = &qeth_l3_netdev_ops;
qeth_l3_iqd_read_initial_mac(card);
} else
return -ENODEV;
@@ -2944,7 +2961,6 @@ static int qeth_l3_setup_netdev(struct qeth_card *card)
card->dev->ml_priv = card;
card->dev->watchdog_timeo = QETH_TX_TIMEOUT;
card->dev->mtu = card->info.initial_mtu;
- card->dev->netdev_ops = &qeth_l3_netdev_ops;
SET_ETHTOOL_OPS(card->dev, &qeth_l3_ethtool_ops);
card->dev->features |= NETIF_F_HW_VLAN_TX |
NETIF_F_HW_VLAN_RX |
diff --git a/drivers/serial/8250.c b/drivers/serial/8250.c
index 1889a63..0d934bf 100644
--- a/drivers/serial/8250.c
+++ b/drivers/serial/8250.c
@@ -2839,6 +2839,8 @@ int __init early_serial_setup(struct uart_port *port)
p->flags = port->flags;
p->mapbase = port->mapbase;
p->private_data = port->private_data;
+ p->type = port->type;
+ p->line = port->line;
set_io_from_upio(p);
if (port->serial_in)
diff --git a/drivers/serial/jsm/jsm_neo.c b/drivers/serial/jsm/jsm_neo.c
index b7584ca..e6390d0 100644
--- a/drivers/serial/jsm/jsm_neo.c
+++ b/drivers/serial/jsm/jsm_neo.c
@@ -577,9 +577,6 @@ static void neo_parse_modem(struct jsm_channel *ch, u8 signals)
jsm_printk(MSIGS, INFO, &ch->ch_bd->pci_dev,
"neo_parse_modem: port: %d msignals: %x\n", ch->ch_portnum, msignals);
- if (!ch)
- return;
-
/* Scrub off lower bits. They signify delta's, which I don't care about */
/* Keep DDCD and DDSR though */
msignals &= 0xf8;
diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c
index 01d0c70..3cf41df 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.c
+++ b/drivers/usb/serial/ti_usb_3410_5052.c
@@ -145,7 +145,7 @@ static int ti_command_in_sync(struct ti_device *tdev, __u8 command,
static int ti_write_byte(struct ti_device *tdev, unsigned long addr,
__u8 mask, __u8 byte);
-static int ti_download_firmware(struct ti_device *tdev, int type);
+static int ti_download_firmware(struct ti_device *tdev);
/* circular buffer */
static struct circ_buf *ti_buf_alloc(void);
@@ -176,9 +176,14 @@ static unsigned int product_5052_count;
/* the array dimension is the number of default entries plus */
/* TI_EXTRA_VID_PID_COUNT user defined entries plus 1 terminating */
/* null entry */
-static struct usb_device_id ti_id_table_3410[1+TI_EXTRA_VID_PID_COUNT+1] = {
+static struct usb_device_id ti_id_table_3410[7+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_NO_FW_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) },
};
static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = {
@@ -188,9 +193,14 @@ static struct usb_device_id ti_id_table_5052[4+TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_FIRMWARE_PRODUCT_ID) },
};
-static struct usb_device_id ti_id_table_combined[] = {
+static struct usb_device_id ti_id_table_combined[6+2*TI_EXTRA_VID_PID_COUNT+1] = {
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_3410_EZ430_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_NO_FW_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_NO_FW_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_CDMA_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_GSM_PRODUCT_ID) },
+ { USB_DEVICE(MTS_VENDOR_ID, MTS_EDGE_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_BOOT_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5152_BOOT_PRODUCT_ID) },
{ USB_DEVICE(TI_VENDOR_ID, TI_5052_EEPROM_PRODUCT_ID) },
@@ -272,6 +282,9 @@ MODULE_LICENSE("GPL");
MODULE_FIRMWARE("ti_3410.fw");
MODULE_FIRMWARE("ti_5052.fw");
+MODULE_FIRMWARE("mts_cdma.fw");
+MODULE_FIRMWARE("mts_gsm.fw");
+MODULE_FIRMWARE("mts_edge.fw");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Enable debugging, 0=no, 1=yes");
@@ -304,21 +317,28 @@ MODULE_DEVICE_TABLE(usb, ti_id_table_combined);
static int __init ti_init(void)
{
- int i, j;
+ int i, j, c;
int ret;
/* insert extra vendor and product ids */
+ c = ARRAY_SIZE(ti_id_table_combined) - 2 * TI_EXTRA_VID_PID_COUNT - 1;
j = ARRAY_SIZE(ti_id_table_3410) - TI_EXTRA_VID_PID_COUNT - 1;
- for (i = 0; i < min(vendor_3410_count, product_3410_count); i++, j++) {
+ for (i = 0; i < min(vendor_3410_count, product_3410_count); i++, j++, c++) {
ti_id_table_3410[j].idVendor = vendor_3410[i];
ti_id_table_3410[j].idProduct = product_3410[i];
ti_id_table_3410[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+ ti_id_table_combined[c].idVendor = vendor_3410[i];
+ ti_id_table_combined[c].idProduct = product_3410[i];
+ ti_id_table_combined[c].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
}
j = ARRAY_SIZE(ti_id_table_5052) - TI_EXTRA_VID_PID_COUNT - 1;
- for (i = 0; i < min(vendor_5052_count, product_5052_count); i++, j++) {
+ for (i = 0; i < min(vendor_5052_count, product_5052_count); i++, j++, c++) {
ti_id_table_5052[j].idVendor = vendor_5052[i];
ti_id_table_5052[j].idProduct = product_5052[i];
ti_id_table_5052[j].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+ ti_id_table_combined[c].idVendor = vendor_5052[i];
+ ti_id_table_combined[c].idProduct = product_5052[i];
+ ti_id_table_combined[c].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
}
ret = usb_serial_register(&ti_1port_device);
@@ -390,11 +410,7 @@ static int ti_startup(struct usb_serial *serial)
/* if we have only 1 configuration, download firmware */
if (dev->descriptor.bNumConfigurations == 1) {
- if (tdev->td_is_3410)
- status = ti_download_firmware(tdev, 3410);
- else
- status = ti_download_firmware(tdev, 5052);
- if (status)
+ if ((status = ti_download_firmware(tdev)) != 0)
goto free_tdev;
/* 3410 must be reset, 5052 resets itself */
@@ -1671,9 +1687,9 @@ static int ti_do_download(struct usb_device *dev, int pipe,
return status;
}
-static int ti_download_firmware(struct ti_device *tdev, int type)
+static int ti_download_firmware(struct ti_device *tdev)
{
- int status = -ENOMEM;
+ int status;
int buffer_size;
__u8 *buffer;
struct usb_device *dev = tdev->td_serial->dev;
@@ -1681,9 +1697,34 @@ static int ti_download_firmware(struct ti_device *tdev, int type)
tdev->td_serial->port[0]->bulk_out_endpointAddress);
const struct firmware *fw_p;
char buf[32];
- sprintf(buf, "ti_usb-%d.bin", type);
- if (request_firmware(&fw_p, buf, &dev->dev)) {
+ /* try ID specific firmware first, then try generic firmware */
+ sprintf(buf, "ti_usb-v%04x-p%04x.fw", dev->descriptor.idVendor,
+ dev->descriptor.idProduct);
+ if ((status = request_firmware(&fw_p, buf, &dev->dev)) != 0) {
+ buf[0] = '\0';
+ if (dev->descriptor.idVendor == MTS_VENDOR_ID) {
+ switch (dev->descriptor.idProduct) {
+ case MTS_CDMA_PRODUCT_ID:
+ strcpy(buf, "mts_cdma.fw");
+ break;
+ case MTS_GSM_PRODUCT_ID:
+ strcpy(buf, "mts_gsm.fw");
+ break;
+ case MTS_EDGE_PRODUCT_ID:
+ strcpy(buf, "mts_edge.fw");
+ break;
+ }
+ }
+ if (buf[0] == '\0') {
+ if (tdev->td_is_3410)
+ strcpy(buf, "ti_3410.fw");
+ else
+ strcpy(buf, "ti_5052.fw");
+ }
+ status = request_firmware(&fw_p, buf, &dev->dev);
+ }
+ if (status) {
dev_err(&dev->dev, "%s - firmware not found\n", __func__);
return -ENOENT;
}
@@ -1699,6 +1740,8 @@ static int ti_download_firmware(struct ti_device *tdev, int type)
memset(buffer + fw_p->size, 0xff, buffer_size - fw_p->size);
status = ti_do_download(dev, pipe, buffer, fw_p->size);
kfree(buffer);
+ } else {
+ status = -ENOMEM;
}
release_firmware(fw_p);
if (status) {
diff --git a/drivers/usb/serial/ti_usb_3410_5052.h b/drivers/usb/serial/ti_usb_3410_5052.h
index b5541bf..7e4752f 100644
--- a/drivers/usb/serial/ti_usb_3410_5052.h
+++ b/drivers/usb/serial/ti_usb_3410_5052.h
@@ -34,6 +34,14 @@
#define TI_5052_EEPROM_PRODUCT_ID 0x505A /* EEPROM, no firmware */
#define TI_5052_FIRMWARE_PRODUCT_ID 0x505F /* firmware is running */
+/* Multi-Tech vendor and product ids */
+#define MTS_VENDOR_ID 0x06E0
+#define MTS_GSM_NO_FW_PRODUCT_ID 0xF108
+#define MTS_CDMA_NO_FW_PRODUCT_ID 0xF109
+#define MTS_CDMA_PRODUCT_ID 0xF110
+#define MTS_GSM_PRODUCT_ID 0xF111
+#define MTS_EDGE_PRODUCT_ID 0xF112
+
/* Commands */
#define TI_GET_VERSION 0x01
#define TI_GET_PORT_STATUS 0x02
diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c
index 080ade2..cfcfd5a 100644
--- a/drivers/usb/serial/usb-serial.c
+++ b/drivers/usb/serial/usb-serial.c
@@ -511,9 +511,6 @@ static void usb_serial_port_work(struct work_struct *work)
dbg("%s - port %d", __func__, port->number);
- if (!port)
- return;
-
tty = tty_port_tty_get(&port->port);
if (!tty)
return;
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index e39e33e..be2b657 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -28,7 +28,7 @@ obj-$(CONFIG_FB_DDC) += fb_ddc.o
obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o
# Hardware specific drivers go first
-obj-$(CONFIG_FB_AMIGA) += amifb.o c2p.o
+obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o
obj-$(CONFIG_FB_ARC) += arcfb.o
obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o
obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o
@@ -72,7 +72,7 @@ obj-$(CONFIG_FB_TCX) += tcx.o sbuslib.o
obj-$(CONFIG_FB_LEO) += leo.o sbuslib.o
obj-$(CONFIG_FB_SGIVW) += sgivwfb.o
obj-$(CONFIG_FB_ACORN) += acornfb.o
-obj-$(CONFIG_FB_ATARI) += atafb.o c2p.o atafb_mfb.o \
+obj-$(CONFIG_FB_ATARI) += atafb.o c2p_iplan2.o atafb_mfb.o \
atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
obj-$(CONFIG_FB_MAC) += macfb.o
obj-$(CONFIG_FB_HECUBA) += hecubafb.o
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index b8e9a86..100f236 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -2159,9 +2159,9 @@ static void amifb_imageblit(struct fb_info *info, const struct fb_image *image)
src += pitch;
}
} else {
- c2p(info->screen_base, image->data, dx, dy, width, height,
- par->next_line, par->next_plane, image->width,
- info->var.bits_per_pixel);
+ c2p_planar(info->screen_base, image->data, dx, dy, width,
+ height, par->next_line, par->next_plane,
+ image->width, info->var.bits_per_pixel);
}
}
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index 77eb8b3..8058572 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -122,7 +122,6 @@ static struct atafb_par {
void *screen_base;
int yres_virtual;
u_long next_line;
- u_long next_plane;
#if defined ATAFB_TT || defined ATAFB_STE
union {
struct {
@@ -149,6 +148,7 @@ static struct atafb_par {
short mono;
short ste_mode;
short bpp;
+ u32 pseudo_palette[16];
} falcon;
#endif
/* Nothing needed for external mode */
@@ -614,7 +614,7 @@ static int tt_encode_fix(struct fb_fix_screeninfo *fix, struct atafb_par *par)
fix->xpanstep = 0;
fix->ypanstep = 1;
fix->ywrapstep = 0;
- fix->line_length = 0;
+ fix->line_length = par->next_line;
fix->accel = FB_ACCEL_ATARIBLITT;
return 0;
}
@@ -691,6 +691,7 @@ static int tt_decode_var(struct fb_var_screeninfo *var, struct atafb_par *par)
return -EINVAL;
par->yres_virtual = yres_virtual;
par->screen_base = screen_base + var->yoffset * linelen;
+ par->next_line = linelen;
return 0;
}
@@ -884,10 +885,6 @@ static int vdl_prescale[4][3] = {
/* Default hsync timing [mon_type] in picoseconds */
static long h_syncs[4] = { 3000000, 4875000, 4000000, 4875000 };
-#ifdef FBCON_HAS_CFB16
-static u16 fbcon_cfb16_cmap[16];
-#endif
-
static inline int hxx_prescale(struct falcon_hw *hw)
{
return hw->ste_mode ? 16
@@ -918,7 +915,7 @@ static int falcon_encode_fix(struct fb_fix_screeninfo *fix,
fix->visual = FB_VISUAL_TRUECOLOR;
fix->xpanstep = 2;
}
- fix->line_length = 0;
+ fix->line_length = par->next_line;
fix->accel = FB_ACCEL_ATARIBLITT;
return 0;
}
@@ -1394,14 +1391,7 @@ set_screen_base:
par->screen_base = screen_base + var->yoffset * linelen;
par->hw.falcon.xoffset = 0;
- // FIXME!!! sort of works, no crash
- //par->next_line = linelen;
- //par->next_plane = yres_virtual * linelen;
par->next_line = linelen;
- par->next_plane = 2;
- // crashes
- //par->next_plane = linelen;
- //par->next_line = yres_virtual * linelen;
return 0;
}
@@ -1735,10 +1725,10 @@ static int falcon_setcolreg(unsigned int regno, unsigned int red,
(((red & 0xe000) >> 13) | ((red & 0x1000) >> 12) << 8) |
(((green & 0xe000) >> 13) | ((green & 0x1000) >> 12) << 4) |
((blue & 0xe000) >> 13) | ((blue & 0x1000) >> 12);
-#ifdef FBCON_HAS_CFB16
- fbcon_cfb16_cmap[regno] = ((red & 0xf800) |
- ((green & 0xfc00) >> 5) |
- ((blue & 0xf800) >> 11));
+#ifdef ATAFB_FALCON
+ ((u32 *)info->pseudo_palette)[regno] = ((red & 0xf800) |
+ ((green & 0xfc00) >> 5) |
+ ((blue & 0xf800) >> 11));
#endif
}
return 0;
@@ -1852,7 +1842,7 @@ static int stste_encode_fix(struct fb_fix_screeninfo *fix,
fix->ypanstep = 0;
}
fix->ywrapstep = 0;
- fix->line_length = 0;
+ fix->line_length = par->next_line;
fix->accel = FB_ACCEL_ATARIBLITT;
return 0;
}
@@ -1910,6 +1900,7 @@ static int stste_decode_var(struct fb_var_screeninfo *var,
return -EINVAL;
par->yres_virtual = yres_virtual;
par->screen_base = screen_base + var->yoffset * linelen;
+ par->next_line = linelen;
return 0;
}
@@ -2169,7 +2160,7 @@ static int ext_encode_fix(struct fb_fix_screeninfo *fix, struct atafb_par *par)
fix->xpanstep = 0;
fix->ypanstep = 0;
fix->ywrapstep = 0;
- fix->line_length = 0;
+ fix->line_length = par->next_line;
return 0;
}
@@ -2184,6 +2175,8 @@ static int ext_decode_var(struct fb_var_screeninfo *var, struct atafb_par *par)
var->xoffset > 0 ||
var->yoffset > 0)
return -EINVAL;
+
+ par->next_line = external_xres_virtual * external_depth / 8;
return 0;
}
@@ -2443,42 +2436,6 @@ static void atafb_set_disp(struct fb_info *info)
atafb_get_fix(&info->fix, info);
info->screen_base = (void *)info->fix.smem_start;
-
- switch (info->fix.type) {
- case FB_TYPE_INTERLEAVED_PLANES:
- switch (info->var.bits_per_pixel) {
- case 2:
- // display->dispsw = &fbcon_iplan2p2;
- break;
- case 4:
- // display->dispsw = &fbcon_iplan2p4;
- break;
- case 8:
- // display->dispsw = &fbcon_iplan2p8;
- break;
- }
- break;
- case FB_TYPE_PACKED_PIXELS:
- switch (info->var.bits_per_pixel) {
-#ifdef FBCON_HAS_MFB
- case 1:
- // display->dispsw = &fbcon_mfb;
- break;
-#endif
-#ifdef FBCON_HAS_CFB8
- case 8:
- // display->dispsw = &fbcon_cfb8;
- break;
-#endif
-#ifdef FBCON_HAS_CFB16
- case 16:
- // display->dispsw = &fbcon_cfb16;
- // display->dispsw_data = fbcon_cfb16_cmap;
- break;
-#endif
- }
- break;
- }
}
static int atafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
@@ -2549,6 +2506,13 @@ static void atafb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
if (!rect->width || !rect->height)
return;
+#ifdef ATAFB_FALCON
+ if (info->var.bits_per_pixel == 16) {
+ cfb_fillrect(info, rect);
+ return;
+ }
+#endif
+
/*
* We could use hardware clipping but on many cards you get around
* hardware clipping by writing to framebuffer directly.
@@ -2583,6 +2547,13 @@ static void atafb_copyarea(struct fb_info *info, const struct fb_copyarea *area)
u32 dx, dy, sx, sy, width, height;
int rev_copy = 0;
+#ifdef ATAFB_FALCON
+ if (info->var.bits_per_pixel == 16) {
+ cfb_copyarea(info, area);
+ return;
+ }
+#endif
+
/* clip the destination */
x2 = area->dx + area->width;
y2 = area->dy + area->height;
@@ -2632,6 +2603,13 @@ static void atafb_imageblit(struct fb_info *info, const struct fb_image *image)
const char *src;
u32 dx, dy, width, height, pitch;
+#ifdef ATAFB_FALCON
+ if (info->var.bits_per_pixel == 16) {
+ cfb_imageblit(info, image);
+ return;
+ }
+#endif
+
/*
* We could use hardware clipping but on many cards you get around
* hardware clipping by writing to framebuffer directly like we are
@@ -2676,10 +2654,9 @@ static void atafb_imageblit(struct fb_info *info, const struct fb_image *image)
src += pitch;
}
} else {
- // only used for logo; broken
- c2p(info->screen_base, image->data, dx, dy, width, height,
- par->next_line, par->next_plane, image->width,
- info->var.bits_per_pixel);
+ c2p_iplan2(info->screen_base, image->data, dx, dy, width,
+ height, par->next_line, image->width,
+ info->var.bits_per_pixel);
}
}
@@ -3098,8 +3075,7 @@ int __init atafb_setup(char *options)
int __init atafb_init(void)
{
- int pad;
- int detected_mode;
+ int pad, detected_mode, error;
unsigned int defmode = 0;
unsigned long mem_req;
@@ -3139,8 +3115,12 @@ int __init atafb_init(void)
printk("atafb_init: initializing Falcon hw\n");
fbhw = &falcon_switch;
atafb_ops.fb_setcolreg = &falcon_setcolreg;
- request_irq(IRQ_AUTO_4, falcon_vbl_switcher, IRQ_TYPE_PRIO,
- "framebuffer/modeswitch", falcon_vbl_switcher);
+ error = request_irq(IRQ_AUTO_4, falcon_vbl_switcher,
+ IRQ_TYPE_PRIO,
+ "framebuffer/modeswitch",
+ falcon_vbl_switcher);
+ if (error)
+ return error;
defmode = DEFMODE_F30;
break;
}
@@ -3225,6 +3205,10 @@ int __init atafb_init(void)
// tries to read from HW which may not be initialized yet
// so set sane var first, then call atafb_set_par
atafb_get_var(&fb_info.var, &fb_info);
+
+#ifdef ATAFB_FALCON
+ fb_info.pseudo_palette = current_par.hw.falcon.pseudo_palette;
+#endif
fb_info.flags = FBINFO_FLAG_DEFAULT;
if (!fb_find_mode(&fb_info.var, &fb_info, mode_option, atafb_modedb,
diff --git a/drivers/video/c2p.c b/drivers/video/c2p.c
deleted file mode 100644
index 376bc07..0000000
--- a/drivers/video/c2p.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * Fast C2P (Chunky-to-Planar) Conversion
- *
- * Copyright (C) 2003 Geert Uytterhoeven
- *
- * NOTES:
- * - This code was inspired by Scout's C2P tutorial
- * - It assumes to run on a big endian system
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file COPYING in the main directory of this archive
- * for more details.
- */
-
-#include <linux/module.h>
-#include <linux/string.h>
-#include "c2p.h"
-
-
- /*
- * Basic transpose step
- */
-
-#define _transp(d, i1, i2, shift, mask) \
- do { \
- u32 t = (d[i1] ^ (d[i2] >> shift)) & mask; \
- d[i1] ^= t; \
- d[i2] ^= t << shift; \
- } while (0)
-
-static inline u32 get_mask(int n)
-{
- switch (n) {
- case 1:
- return 0x55555555;
- break;
-
- case 2:
- return 0x33333333;
- break;
-
- case 4:
- return 0x0f0f0f0f;
- break;
-
- case 8:
- return 0x00ff00ff;
- break;
-
- case 16:
- return 0x0000ffff;
- break;
- }
- return 0;
-}
-
-#define transp_nx1(d, n) \
- do { \
- u32 mask = get_mask(n); \
- /* First block */ \
- _transp(d, 0, 1, n, mask); \
- /* Second block */ \
- _transp(d, 2, 3, n, mask); \
- /* Third block */ \
- _transp(d, 4, 5, n, mask); \
- /* Fourth block */ \
- _transp(d, 6, 7, n, mask); \
- } while (0)
-
-#define transp_nx2(d, n) \
- do { \
- u32 mask = get_mask(n); \
- /* First block */ \
- _transp(d, 0, 2, n, mask); \
- _transp(d, 1, 3, n, mask); \
- /* Second block */ \
- _transp(d, 4, 6, n, mask); \
- _transp(d, 5, 7, n, mask); \
- } while (0)
-
-#define transp_nx4(d, n) \
- do { \
- u32 mask = get_mask(n); \
- _transp(d, 0, 4, n, mask); \
- _transp(d, 1, 5, n, mask); \
- _transp(d, 2, 6, n, mask); \
- _transp(d, 3, 7, n, mask); \
- } while (0)
-
-#define transp(d, n, m) transp_nx ## m(d, n)
-
-
- /*
- * Perform a full C2P step on 32 8-bit pixels, stored in 8 32-bit words
- * containing
- * - 32 8-bit chunky pixels on input
- * - permuted planar data on output
- */
-
-static void c2p_8bpp(u32 d[8])
-{
- transp(d, 16, 4);
- transp(d, 8, 2);
- transp(d, 4, 1);
- transp(d, 2, 4);
- transp(d, 1, 2);
-}
-
-
- /*
- * Array containing the permution indices of the planar data after c2p
- */
-
-static const int perm_c2p_8bpp[8] = { 7, 5, 3, 1, 6, 4, 2, 0 };
-
-
- /*
- * Compose two values, using a bitmask as decision value
- * This is equivalent to (a & mask) | (b & ~mask)
- */
-
-static inline unsigned long comp(unsigned long a, unsigned long b,
- unsigned long mask)
-{
- return ((a ^ b) & mask) ^ b;
-}
-
-
- /*
- * Store a full block of planar data after c2p conversion
- */
-
-static inline void store_planar(char *dst, u32 dst_inc, u32 bpp, u32 d[8])
-{
- int i;
-
- for (i = 0; i < bpp; i++, dst += dst_inc)
- *(u32 *)dst = d[perm_c2p_8bpp[i]];
-}
-
-
- /*
- * Store a partial block of planar data after c2p conversion
- */
-
-static inline void store_planar_masked(char *dst, u32 dst_inc, u32 bpp,
- u32 d[8], u32 mask)
-{
- int i;
-
- for (i = 0; i < bpp; i++, dst += dst_inc)
- *(u32 *)dst = comp(d[perm_c2p_8bpp[i]], *(u32 *)dst, mask);
-}
-
-
- /*
- * c2p - Copy 8-bit chunky image data to a planar frame buffer
- * @dst: Starting address of the planar frame buffer
- * @dx: Horizontal destination offset (in pixels)
- * @dy: Vertical destination offset (in pixels)
- * @width: Image width (in pixels)
- * @height: Image height (in pixels)
- * @dst_nextline: Frame buffer offset to the next line (in bytes)
- * @dst_nextplane: Frame buffer offset to the next plane (in bytes)
- * @src_nextline: Image offset to the next line (in bytes)
- * @bpp: Bits per pixel of the planar frame buffer (1-8)
- */
-
-void c2p(u8 *dst, const u8 *src, u32 dx, u32 dy, u32 width, u32 height,
- u32 dst_nextline, u32 dst_nextplane, u32 src_nextline, u32 bpp)
-{
- int dst_idx;
- u32 d[8], first, last, w;
- const u8 *c;
- u8 *p;
-
- dst += dy*dst_nextline+(dx & ~31);
- dst_idx = dx % 32;
- first = ~0UL >> dst_idx;
- last = ~(~0UL >> ((dst_idx+width) % 32));
- while (height--) {
- c = src;
- p = dst;
- w = width;
- if (dst_idx+width <= 32) {
- /* Single destination word */
- first &= last;
- memset(d, 0, sizeof(d));
- memcpy((u8 *)d+dst_idx, c, width);
- c += width;
- c2p_8bpp(d);
- store_planar_masked(p, dst_nextplane, bpp, d, first);
- p += 4;
- } else {
- /* Multiple destination words */
- w = width;
- /* Leading bits */
- if (dst_idx) {
- w = 32 - dst_idx;
- memset(d, 0, dst_idx);
- memcpy((u8 *)d+dst_idx, c, w);
- c += w;
- c2p_8bpp(d);
- store_planar_masked(p, dst_nextplane, bpp, d, first);
- p += 4;
- w = width-w;
- }
- /* Main chunk */
- while (w >= 32) {
- memcpy(d, c, 32);
- c += 32;
- c2p_8bpp(d);
- store_planar(p, dst_nextplane, bpp, d);
- p += 4;
- w -= 32;
- }
- /* Trailing bits */
- w %= 32;
- if (w > 0) {
- memcpy(d, c, w);
- memset((u8 *)d+w, 0, 32-w);
- c2p_8bpp(d);
- store_planar_masked(p, dst_nextplane, bpp, d, last);
- }
- }
- src += src_nextline;
- dst += dst_nextline;
- }
-}
-EXPORT_SYMBOL_GPL(c2p);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/video/c2p.h b/drivers/video/c2p.h
index c77cbf1..6c38d40 100644
--- a/drivers/video/c2p.h
+++ b/drivers/video/c2p.h
@@ -1,7 +1,7 @@
/*
* Fast C2P (Chunky-to-Planar) Conversion
*
- * Copyright (C) 2003 Geert Uytterhoeven
+ * Copyright (C) 2003-2008 Geert Uytterhoeven
*
* 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
@@ -10,7 +10,10 @@
#include <linux/types.h>
-extern void c2p(u8 *dst, const u8 *src, u32 dx, u32 dy, u32 width, u32 height,
- u32 dst_nextline, u32 dst_nextplane, u32 src_nextline,
- u32 bpp);
+extern void c2p_planar(void *dst, const void *src, u32 dx, u32 dy, u32 width,
+ u32 height, u32 dst_nextline, u32 dst_nextplane,
+ u32 src_nextline, u32 bpp);
+extern void c2p_iplan2(void *dst, const void *src, u32 dx, u32 dy, u32 width,
+ u32 height, u32 dst_nextline, u32 src_nextline,
+ u32 bpp);
diff --git a/drivers/video/c2p_core.h b/drivers/video/c2p_core.h
new file mode 100644
index 0000000..e1035a8
--- /dev/null
+++ b/drivers/video/c2p_core.h
@@ -0,0 +1,153 @@
+/*
+ * Fast C2P (Chunky-to-Planar) Conversion
+ *
+ * Copyright (C) 2003-2008 Geert Uytterhoeven
+ *
+ * NOTES:
+ * - This code was inspired by Scout's C2P tutorial
+ * - It assumes to run on a big endian system
+ *
+ * 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.
+ */
+
+
+ /*
+ * Basic transpose step
+ */
+
+static inline void _transp(u32 d[], unsigned int i1, unsigned int i2,
+ unsigned int shift, u32 mask)
+{
+ u32 t = (d[i1] ^ (d[i2] >> shift)) & mask;
+
+ d[i1] ^= t;
+ d[i2] ^= t << shift;
+}
+
+
+extern void c2p_unsupported(void);
+
+static inline u32 get_mask(unsigned int n)
+{
+ switch (n) {
+ case 1:
+ return 0x55555555;
+
+ case 2:
+ return 0x33333333;
+
+ case 4:
+ return 0x0f0f0f0f;
+
+ case 8:
+ return 0x00ff00ff;
+
+ case 16:
+ return 0x0000ffff;
+ }
+
+ c2p_unsupported();
+ return 0;
+}
+
+
+ /*
+ * Transpose operations on 8 32-bit words
+ */
+
+static inline void transp8(u32 d[], unsigned int n, unsigned int m)
+{
+ u32 mask = get_mask(n);
+
+ switch (m) {
+ case 1:
+ /* First n x 1 block */
+ _transp(d, 0, 1, n, mask);
+ /* Second n x 1 block */
+ _transp(d, 2, 3, n, mask);
+ /* Third n x 1 block */
+ _transp(d, 4, 5, n, mask);
+ /* Fourth n x 1 block */
+ _transp(d, 6, 7, n, mask);
+ return;
+
+ case 2:
+ /* First n x 2 block */
+ _transp(d, 0, 2, n, mask);
+ _transp(d, 1, 3, n, mask);
+ /* Second n x 2 block */
+ _transp(d, 4, 6, n, mask);
+ _transp(d, 5, 7, n, mask);
+ return;
+
+ case 4:
+ /* Single n x 4 block */
+ _transp(d, 0, 4, n, mask);
+ _transp(d, 1, 5, n, mask);
+ _transp(d, 2, 6, n, mask);
+ _transp(d, 3, 7, n, mask);
+ return;
+ }
+
+ c2p_unsupported();
+}
+
+
+ /*
+ * Transpose operations on 4 32-bit words
+ */
+
+static inline void transp4(u32 d[], unsigned int n, unsigned int m)
+{
+ u32 mask = get_mask(n);
+
+ switch (m) {
+ case 1:
+ /* First n x 1 block */
+ _transp(d, 0, 1, n, mask);
+ /* Second n x 1 block */
+ _transp(d, 2, 3, n, mask);
+ return;
+
+ case 2:
+ /* Single n x 2 block */
+ _transp(d, 0, 2, n, mask);
+ _transp(d, 1, 3, n, mask);
+ return;
+ }
+
+ c2p_unsupported();
+}
+
+
+ /*
+ * Transpose operations on 4 32-bit words (reverse order)
+ */
+
+static inline void transp4x(u32 d[], unsigned int n, unsigned int m)
+{
+ u32 mask = get_mask(n);
+
+ switch (m) {
+ case 2:
+ /* Single n x 2 block */
+ _transp(d, 2, 0, n, mask);
+ _transp(d, 3, 1, n, mask);
+ return;
+ }
+
+ c2p_unsupported();
+}
+
+
+ /*
+ * Compose two values, using a bitmask as decision value
+ * This is equivalent to (a & mask) | (b & ~mask)
+ */
+
+static inline u32 comp(u32 a, u32 b, u32 mask)
+{
+ return ((a ^ b) & mask) ^ b;
+}
diff --git a/drivers/video/c2p_iplan2.c b/drivers/video/c2p_iplan2.c
new file mode 100644
index 0000000..19156dc
--- /dev/null
+++ b/drivers/video/c2p_iplan2.c
@@ -0,0 +1,153 @@
+/*
+ * Fast C2P (Chunky-to-Planar) Conversion
+ *
+ * Copyright (C) 2003-2008 Geert Uytterhoeven
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+
+#include <asm/unaligned.h>
+
+#include "c2p.h"
+#include "c2p_core.h"
+
+
+ /*
+ * Perform a full C2P step on 16 8-bit pixels, stored in 4 32-bit words
+ * containing
+ * - 16 8-bit chunky pixels on input
+ * - permutated planar data (2 planes per 32-bit word) on output
+ */
+
+static void c2p_16x8(u32 d[4])
+{
+ transp4(d, 8, 2);
+ transp4(d, 1, 2);
+ transp4x(d, 16, 2);
+ transp4x(d, 2, 2);
+ transp4(d, 4, 1);
+}
+
+
+ /*
+ * Array containing the permutation indices of the planar data after c2p
+ */
+
+static const int perm_c2p_16x8[4] = { 1, 3, 0, 2 };
+
+
+ /*
+ * Store a full block of iplan2 data after c2p conversion
+ */
+
+static inline void store_iplan2(void *dst, u32 bpp, u32 d[4])
+{
+ int i;
+
+ for (i = 0; i < bpp/2; i++, dst += 4)
+ put_unaligned_be32(d[perm_c2p_16x8[i]], dst);
+}
+
+
+ /*
+ * Store a partial block of iplan2 data after c2p conversion
+ */
+
+static inline void store_iplan2_masked(void *dst, u32 bpp, u32 d[4], u32 mask)
+{
+ int i;
+
+ for (i = 0; i < bpp/2; i++, dst += 4)
+ put_unaligned_be32(comp(d[perm_c2p_16x8[i]],
+ get_unaligned_be32(dst), mask),
+ dst);
+}
+
+
+ /*
+ * c2p_iplan2 - Copy 8-bit chunky image data to an interleaved planar
+ * frame buffer with 2 bytes of interleave
+ * @dst: Starting address of the planar frame buffer
+ * @dx: Horizontal destination offset (in pixels)
+ * @dy: Vertical destination offset (in pixels)
+ * @width: Image width (in pixels)
+ * @height: Image height (in pixels)
+ * @dst_nextline: Frame buffer offset to the next line (in bytes)
+ * @src_nextline: Image offset to the next line (in bytes)
+ * @bpp: Bits per pixel of the planar frame buffer (2, 4, or 8)
+ */
+
+void c2p_iplan2(void *dst, const void *src, u32 dx, u32 dy, u32 width,
+ u32 height, u32 dst_nextline, u32 src_nextline, u32 bpp)
+{
+ union {
+ u8 pixels[16];
+ u32 words[4];
+ } d;
+ u32 dst_idx, first, last, w;
+ const u8 *c;
+ void *p;
+
+ dst += dy*dst_nextline+(dx & ~15)*bpp;
+ dst_idx = dx % 16;
+ first = 0xffffU >> dst_idx;
+ first |= first << 16;
+ last = 0xffffU ^ (0xffffU >> ((dst_idx+width) % 16));
+ last |= last << 16;
+ while (height--) {
+ c = src;
+ p = dst;
+ w = width;
+ if (dst_idx+width <= 16) {
+ /* Single destination word */
+ first &= last;
+ memset(d.pixels, 0, sizeof(d));
+ memcpy(d.pixels+dst_idx, c, width);
+ c += width;
+ c2p_16x8(d.words);
+ store_iplan2_masked(p, bpp, d.words, first);
+ p += bpp*2;
+ } else {
+ /* Multiple destination words */
+ w = width;
+ /* Leading bits */
+ if (dst_idx) {
+ w = 16 - dst_idx;
+ memset(d.pixels, 0, dst_idx);
+ memcpy(d.pixels+dst_idx, c, w);
+ c += w;
+ c2p_16x8(d.words);
+ store_iplan2_masked(p, bpp, d.words, first);
+ p += bpp*2;
+ w = width-w;
+ }
+ /* Main chunk */
+ while (w >= 16) {
+ memcpy(d.pixels, c, 16);
+ c += 16;
+ c2p_16x8(d.words);
+ store_iplan2(p, bpp, d.words);
+ p += bpp*2;
+ w -= 16;
+ }
+ /* Trailing bits */
+ w %= 16;
+ if (w > 0) {
+ memcpy(d.pixels, c, w);
+ memset(d.pixels+w, 0, 16-w);
+ c2p_16x8(d.words);
+ store_iplan2_masked(p, bpp, d.words, last);
+ }
+ }
+ src += src_nextline;
+ dst += dst_nextline;
+ }
+}
+EXPORT_SYMBOL_GPL(c2p_iplan2);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/c2p_planar.c b/drivers/video/c2p_planar.c
new file mode 100644
index 0000000..ec7ac85
--- /dev/null
+++ b/drivers/video/c2p_planar.c
@@ -0,0 +1,156 @@
+/*
+ * Fast C2P (Chunky-to-Planar) Conversion
+ *
+ * Copyright (C) 2003-2008 Geert Uytterhoeven
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+
+#include <asm/unaligned.h>
+
+#include "c2p.h"
+#include "c2p_core.h"
+
+
+ /*
+ * Perform a full C2P step on 32 8-bit pixels, stored in 8 32-bit words
+ * containing
+ * - 32 8-bit chunky pixels on input
+ * - permutated planar data (1 plane per 32-bit word) on output
+ */
+
+static void c2p_32x8(u32 d[8])
+{
+ transp8(d, 16, 4);
+ transp8(d, 8, 2);
+ transp8(d, 4, 1);
+ transp8(d, 2, 4);
+ transp8(d, 1, 2);
+}
+
+
+ /*
+ * Array containing the permutation indices of the planar data after c2p
+ */
+
+static const int perm_c2p_32x8[8] = { 7, 5, 3, 1, 6, 4, 2, 0 };
+
+
+ /*
+ * Store a full block of planar data after c2p conversion
+ */
+
+static inline void store_planar(void *dst, u32 dst_inc, u32 bpp, u32 d[8])
+{
+ int i;
+
+ for (i = 0; i < bpp; i++, dst += dst_inc)
+ put_unaligned_be32(d[perm_c2p_32x8[i]], dst);
+}
+
+
+ /*
+ * Store a partial block of planar data after c2p conversion
+ */
+
+static inline void store_planar_masked(void *dst, u32 dst_inc, u32 bpp,
+ u32 d[8], u32 mask)
+{
+ int i;
+
+ for (i = 0; i < bpp; i++, dst += dst_inc)
+ put_unaligned_be32(comp(d[perm_c2p_32x8[i]],
+ get_unaligned_be32(dst), mask),
+ dst);
+}
+
+
+ /*
+ * c2p_planar - Copy 8-bit chunky image data to a planar frame buffer
+ * @dst: Starting address of the planar frame buffer
+ * @dx: Horizontal destination offset (in pixels)
+ * @dy: Vertical destination offset (in pixels)
+ * @width: Image width (in pixels)
+ * @height: Image height (in pixels)
+ * @dst_nextline: Frame buffer offset to the next line (in bytes)
+ * @dst_nextplane: Frame buffer offset to the next plane (in bytes)
+ * @src_nextline: Image offset to the next line (in bytes)
+ * @bpp: Bits per pixel of the planar frame buffer (1-8)
+ */
+
+void c2p_planar(void *dst, const void *src, u32 dx, u32 dy, u32 width,
+ u32 height, u32 dst_nextline, u32 dst_nextplane,
+ u32 src_nextline, u32 bpp)
+{
+ union {
+ u8 pixels[32];
+ u32 words[8];
+ } d;
+ u32 dst_idx, first, last, w;
+ const u8 *c;
+ void *p;
+
+ dst += dy*dst_nextline+(dx & ~31);
+ dst_idx = dx % 32;
+ first = 0xffffffffU >> dst_idx;
+ last = ~(0xffffffffU >> ((dst_idx+width) % 32));
+ while (height--) {
+ c = src;
+ p = dst;
+ w = width;
+ if (dst_idx+width <= 32) {
+ /* Single destination word */
+ first &= last;
+ memset(d.pixels, 0, sizeof(d));
+ memcpy(d.pixels+dst_idx, c, width);
+ c += width;
+ c2p_32x8(d.words);
+ store_planar_masked(p, dst_nextplane, bpp, d.words,
+ first);
+ p += 4;
+ } else {
+ /* Multiple destination words */
+ w = width;
+ /* Leading bits */
+ if (dst_idx) {
+ w = 32 - dst_idx;
+ memset(d.pixels, 0, dst_idx);
+ memcpy(d.pixels+dst_idx, c, w);
+ c += w;
+ c2p_32x8(d.words);
+ store_planar_masked(p, dst_nextplane, bpp,
+ d.words, first);
+ p += 4;
+ w = width-w;
+ }
+ /* Main chunk */
+ while (w >= 32) {
+ memcpy(d.pixels, c, 32);
+ c += 32;
+ c2p_32x8(d.words);
+ store_planar(p, dst_nextplane, bpp, d.words);
+ p += 4;
+ w -= 32;
+ }
+ /* Trailing bits */
+ w %= 32;
+ if (w > 0) {
+ memcpy(d.pixels, c, w);
+ memset(d.pixels+w, 0, 32-w);
+ c2p_32x8(d.words);
+ store_planar_masked(p, dst_nextplane, bpp,
+ d.words, last);
+ }
+ }
+ src += src_nextline;
+ dst += dst_nextline;
+ }
+}
+EXPORT_SYMBOL_GPL(c2p_planar);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index 4bcff81..1657b96 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -78,13 +78,6 @@
#include <asm/fb.h>
#include <asm/irq.h>
#include <asm/system.h>
-#ifdef CONFIG_ATARI
-#include <asm/atariints.h>
-#endif
-#if defined(__mc68000__)
-#include <asm/machdep.h>
-#include <asm/setup.h>
-#endif
#include "fbcon.h"
@@ -155,9 +148,6 @@ static int fbcon_set_origin(struct vc_data *);
#define CURSOR_DRAW_DELAY (1)
-/* # VBL ints between cursor state changes */
-#define ATARI_CURSOR_BLINK_RATE (42)
-
static int vbl_cursor_cnt;
static int fbcon_cursor_noblink;
@@ -403,20 +393,6 @@ static void fb_flashcursor(struct work_struct *work)
release_console_sem();
}
-#ifdef CONFIG_ATARI
-static int cursor_blink_rate;
-static irqreturn_t fb_vbl_handler(int irq, void *dev_id)
-{
- struct fb_info *info = dev_id;
-
- if (vbl_cursor_cnt && --vbl_cursor_cnt == 0) {
- schedule_work(&info->queue);
- vbl_cursor_cnt = cursor_blink_rate;
- }
- return IRQ_HANDLED;
-}
-#endif
-
static void cursor_timer_handler(unsigned long dev_addr)
{
struct fb_info *info = (struct fb_info *) dev_addr;
@@ -1017,15 +993,6 @@ static const char *fbcon_startup(void)
info->var.yres,
info->var.bits_per_pixel);
-#ifdef CONFIG_ATARI
- if (MACH_IS_ATARI) {
- cursor_blink_rate = ATARI_CURSOR_BLINK_RATE;
- (void)request_irq(IRQ_AUTO_4, fb_vbl_handler,
- IRQ_TYPE_PRIO, "framebuffer vbl",
- info);
- }
-#endif /* CONFIG_ATARI */
-
fbcon_add_cursor_timer(info);
fbcon_has_exited = 0;
return display_desc;
@@ -3454,11 +3421,6 @@ static void fbcon_exit(void)
if (fbcon_has_exited)
return;
-#ifdef CONFIG_ATARI
- if (MACH_IS_ATARI)
- free_irq(IRQ_AUTO_4, fb_vbl_handler);
-#endif
-
kfree((void *)softback_buf);
softback_buf = 0UL;
diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig
index ec68c74..3efa12f 100644
--- a/drivers/watchdog/Kconfig
+++ b/drivers/watchdog/Kconfig
@@ -770,6 +770,12 @@ config TXX9_WDT
# POWERPC Architecture
+config GEF_WDT
+ tristate "GE Fanuc Watchdog Timer"
+ depends on GEF_SBC610
+ ---help---
+ Watchdog timer found in a number of GE Fanuc single board computers.
+
config MPC5200_WDT
tristate "MPC5200 Watchdog Timer"
depends on PPC_MPC52xx
@@ -790,6 +796,14 @@ config MV64X60_WDT
tristate "MV64X60 (Marvell Discovery) Watchdog Timer"
depends on MV64X60
+config PIKA_WDT
+ tristate "PIKA FPGA Watchdog"
+ depends on WARP
+ default y
+ help
+ This enables the watchdog in the PIKA FPGA. Currently used on
+ the Warp platform.
+
config BOOKE_WDT
bool "PowerPC Book-E Watchdog Timer"
depends on BOOKE || 4xx
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index c19b866..806b3eb 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -111,9 +111,11 @@ obj-$(CONFIG_TXX9_WDT) += txx9wdt.o
# PARISC Architecture
# POWERPC Architecture
+obj-$(CONFIG_GEF_WDT) += gef_wdt.o
obj-$(CONFIG_MPC5200_WDT) += mpc5200_wdt.o
obj-$(CONFIG_8xxx_WDT) += mpc8xxx_wdt.o
obj-$(CONFIG_MV64X60_WDT) += mv64x60_wdt.o
+obj-$(CONFIG_PIKA_WDT) += pika_wdt.o
obj-$(CONFIG_BOOKE_WDT) += booke_wdt.o
# PPC64 Architecture
diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c
new file mode 100644
index 0000000..f0c2b7a
--- /dev/null
+++ b/drivers/watchdog/gef_wdt.c
@@ -0,0 +1,330 @@
+/*
+ * GE Fanuc watchdog userspace interface
+ *
+ * Author: Martyn Welch <martyn.welch@gefanuc.com>
+ *
+ * Copyright 2008 GE Fanuc Intelligent Platforms Embedded Systems, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * Based on: mv64x60_wdt.c (MV64X60 watchdog userspace interface)
+ * Author: James Chapman <jchapman@katalix.com>
+ */
+
+/* TODO:
+ * This driver does not provide support for the hardwares capability of sending
+ * an interrupt at a programmable threshold.
+ *
+ * This driver currently can only support 1 watchdog - there are 2 in the
+ * hardware that this driver supports. Thus one could be configured as a
+ * process-based watchdog (via /dev/watchdog), the second (using the interrupt
+ * capabilities) a kernel-based watchdog.
+ */
+
+#include <linux/kernel.h>
+#include <linux/compiler.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/io.h>
+#include <linux/uaccess.h>
+
+#include <sysdev/fsl_soc.h>
+
+/*
+ * The watchdog configuration register contains a pair of 2-bit fields,
+ * 1. a reload field, bits 27-26, which triggers a reload of
+ * the countdown register, and
+ * 2. an enable field, bits 25-24, which toggles between
+ * enabling and disabling the watchdog timer.
+ * Bit 31 is a read-only field which indicates whether the
+ * watchdog timer is currently enabled.
+ *
+ * The low 24 bits contain the timer reload value.
+ */
+#define GEF_WDC_ENABLE_SHIFT 24
+#define GEF_WDC_SERVICE_SHIFT 26
+#define GEF_WDC_ENABLED_SHIFT 31
+
+#define GEF_WDC_ENABLED_TRUE 1
+#define GEF_WDC_ENABLED_FALSE 0
+
+/* Flags bits */
+#define GEF_WDOG_FLAG_OPENED 0
+
+static unsigned long wdt_flags;
+static int wdt_status;
+static void __iomem *gef_wdt_regs;
+static int gef_wdt_timeout;
+static int gef_wdt_count;
+static unsigned int bus_clk;
+static char expect_close;
+static DEFINE_SPINLOCK(gef_wdt_spinlock);
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
+ __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+
+static int gef_wdt_toggle_wdc(int enabled_predicate, int field_shift)
+{
+ u32 data;
+ u32 enabled;
+ int ret = 0;
+
+ spin_lock(&gef_wdt_spinlock);
+ data = ioread32be(gef_wdt_regs);
+ enabled = (data >> GEF_WDC_ENABLED_SHIFT) & 1;
+
+ /* only toggle the requested field if enabled state matches predicate */
+ if ((enabled ^ enabled_predicate) == 0) {
+ /* We write a 1, then a 2 -- to the appropriate field */
+ data = (1 << field_shift) | gef_wdt_count;
+ iowrite32be(data, gef_wdt_regs);
+
+ data = (2 << field_shift) | gef_wdt_count;
+ iowrite32be(data, gef_wdt_regs);
+ ret = 1;
+ }
+ spin_unlock(&gef_wdt_spinlock);
+
+ return ret;
+}
+
+static void gef_wdt_service(void)
+{
+ gef_wdt_toggle_wdc(GEF_WDC_ENABLED_TRUE,
+ GEF_WDC_SERVICE_SHIFT);
+}
+
+static void gef_wdt_handler_enable(void)
+{
+ if (gef_wdt_toggle_wdc(GEF_WDC_ENABLED_FALSE,
+ GEF_WDC_ENABLE_SHIFT)) {
+ gef_wdt_service();
+ printk(KERN_NOTICE "gef_wdt: watchdog activated\n");
+ }
+}
+
+static void gef_wdt_handler_disable(void)
+{
+ if (gef_wdt_toggle_wdc(GEF_WDC_ENABLED_TRUE,
+ GEF_WDC_ENABLE_SHIFT))
+ printk(KERN_NOTICE "gef_wdt: watchdog deactivated\n");
+}
+
+static void gef_wdt_set_timeout(unsigned int timeout)
+{
+ /* maximum bus cycle count is 0xFFFFFFFF */
+ if (timeout > 0xFFFFFFFF / bus_clk)
+ timeout = 0xFFFFFFFF / bus_clk;
+
+ /* Register only holds upper 24 bits, bit shifted into lower 24 */
+ gef_wdt_count = (timeout * bus_clk) >> 8;
+ gef_wdt_timeout = timeout;
+}
+
+
+static ssize_t gef_wdt_write(struct file *file, const char __user *data,
+ size_t len, loff_t *ppos)
+{
+ if (len) {
+ if (!nowayout) {
+ size_t i;
+
+ expect_close = 0;
+
+ for (i = 0; i != len; i++) {
+ char c;
+ if (get_user(c, data + i))
+ return -EFAULT;
+ if (c == 'V')
+ expect_close = 42;
+ }
+ }
+ gef_wdt_service();
+ }
+
+ return len;
+}
+
+static long gef_wdt_ioctl(struct file *file, unsigned int cmd,
+ unsigned long arg)
+{
+ int timeout;
+ int options;
+ void __user *argp = (void __user *)arg;
+ static struct watchdog_info info = {
+ .options = WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE |
+ WDIOF_KEEPALIVEPING,
+ .firmware_version = 0,
+ .identity = "GE Fanuc watchdog",
+ };
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ if (copy_to_user(argp, &info, sizeof(info)))
+ return -EFAULT;
+ break;
+
+ case WDIOC_GETSTATUS:
+ case WDIOC_GETBOOTSTATUS:
+ if (put_user(wdt_status, (int __user *)argp))
+ return -EFAULT;
+ wdt_status &= ~WDIOF_KEEPALIVEPING;
+ break;
+
+ case WDIOC_SETOPTIONS:
+ if (get_user(options, (int __user *)argp))
+ return -EFAULT;
+
+ if (options & WDIOS_DISABLECARD)
+ gef_wdt_handler_disable();
+
+ if (options & WDIOS_ENABLECARD)
+ gef_wdt_handler_enable();
+ break;
+
+ case WDIOC_KEEPALIVE:
+ gef_wdt_service();
+ wdt_status |= WDIOF_KEEPALIVEPING;
+ break;
+
+ case WDIOC_SETTIMEOUT:
+ if (get_user(timeout, (int __user *)argp))
+ return -EFAULT;
+ gef_wdt_set_timeout(timeout);
+ /* Fall through */
+
+ case WDIOC_GETTIMEOUT:
+ if (put_user(gef_wdt_timeout, (int __user *)argp))
+ return -EFAULT;
+ break;
+
+ default:
+ return -ENOTTY;
+ }
+
+ return 0;
+}
+
+static int gef_wdt_open(struct inode *inode, struct file *file)
+{
+ if (test_and_set_bit(GEF_WDOG_FLAG_OPENED, &wdt_flags))
+ return -EBUSY;
+
+ if (nowayout)
+ __module_get(THIS_MODULE);
+
+ gef_wdt_handler_enable();
+
+ return nonseekable_open(inode, file);
+}
+
+static int gef_wdt_release(struct inode *inode, struct file *file)
+{
+ if (expect_close == 42)
+ gef_wdt_handler_disable();
+ else {
+ printk(KERN_CRIT
+ "gef_wdt: unexpected close, not stopping timer!\n");
+ gef_wdt_service();
+ }
+ expect_close = 0;
+
+ clear_bit(GEF_WDOG_FLAG_OPENED, &wdt_flags);
+
+ return 0;
+}
+
+static const struct file_operations gef_wdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .write = gef_wdt_write,
+ .unlocked_ioctl = gef_wdt_ioctl,
+ .open = gef_wdt_open,
+ .release = gef_wdt_release,
+};
+
+static struct miscdevice gef_wdt_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &gef_wdt_fops,
+};
+
+
+static int __devinit gef_wdt_probe(struct of_device *dev,
+ const struct of_device_id *match)
+{
+ int timeout = 10;
+ u32 freq;
+
+ bus_clk = 133; /* in MHz */
+
+ freq = fsl_get_sys_freq();
+ if (freq > 0)
+ bus_clk = freq;
+
+ /* Map devices registers into memory */
+ gef_wdt_regs = of_iomap(dev->node, 0);
+ if (gef_wdt_regs == NULL)
+ return -ENOMEM;
+
+ gef_wdt_set_timeout(timeout);
+
+ gef_wdt_handler_disable(); /* in case timer was already running */
+
+ return misc_register(&gef_wdt_miscdev);
+}
+
+static int __devexit gef_wdt_remove(struct platform_device *dev)
+{
+ misc_deregister(&gef_wdt_miscdev);
+
+ gef_wdt_handler_disable();
+
+ iounmap(gef_wdt_regs);
+
+ return 0;
+}
+
+static const struct of_device_id gef_wdt_ids[] = {
+ {
+ .compatible = "gef,fpga-wdt",
+ },
+ {},
+};
+
+static struct of_platform_driver gef_wdt_driver = {
+ .owner = THIS_MODULE,
+ .name = "gef_wdt",
+ .match_table = gef_wdt_ids,
+ .probe = gef_wdt_probe,
+};
+
+static int __init gef_wdt_init(void)
+{
+ printk(KERN_INFO "GE Fanuc watchdog driver\n");
+ return of_register_platform_driver(&gef_wdt_driver);
+}
+
+static void __exit gef_wdt_exit(void)
+{
+ of_unregister_platform_driver(&gef_wdt_driver);
+}
+
+module_init(gef_wdt_init);
+module_exit(gef_wdt_exit);
+
+MODULE_AUTHOR("Martyn Welch <martyn.welch@gefanuc.com>");
+MODULE_DESCRIPTION("GE Fanuc watchdog driver");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+MODULE_ALIAS("platform: gef_wdt");
diff --git a/drivers/watchdog/pika_wdt.c b/drivers/watchdog/pika_wdt.c
new file mode 100644
index 0000000..2d22e99
--- /dev/null
+++ b/drivers/watchdog/pika_wdt.c
@@ -0,0 +1,301 @@
+/*
+ * PIKA FPGA based Watchdog Timer
+ *
+ * Copyright (c) 2008 PIKA Technologies
+ * Sean MacLennan <smaclennan@pikatech.com>
+ */
+
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/miscdevice.h>
+#include <linux/watchdog.h>
+#include <linux/reboot.h>
+#include <linux/jiffies.h>
+#include <linux/timer.h>
+#include <linux/bitops.h>
+#include <linux/uaccess.h>
+#include <linux/io.h>
+#include <linux/of_platform.h>
+
+#define DRV_NAME "PIKA-WDT"
+#define PFX DRV_NAME ": "
+
+/* Hardware timeout in seconds */
+#define WDT_HW_TIMEOUT 2
+
+/* Timer heartbeat (500ms) */
+#define WDT_TIMEOUT (HZ/2)
+
+/* User land timeout */
+#define WDT_HEARTBEAT 15
+static int heartbeat = WDT_HEARTBEAT;
+module_param(heartbeat, int, 0);
+MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds. "
+ "(default = " __MODULE_STRING(WDT_HEARTBEAT) ")");
+
+static int nowayout = WATCHDOG_NOWAYOUT;
+module_param(nowayout, int, 0);
+MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started "
+ "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
+
+static struct {
+ void __iomem *fpga;
+ unsigned long next_heartbeat; /* the next_heartbeat for the timer */
+ unsigned long open;
+ char expect_close;
+ int bootstatus;
+ struct timer_list timer; /* The timer that pings the watchdog */
+} pikawdt_private;
+
+static struct watchdog_info ident = {
+ .identity = DRV_NAME,
+ .options = WDIOF_CARDRESET |
+ WDIOF_SETTIMEOUT |
+ WDIOF_KEEPALIVEPING |
+ WDIOF_MAGICCLOSE,
+};
+
+/*
+ * Reload the watchdog timer. (ie, pat the watchdog)
+ */
+static inline void pikawdt_reset(void)
+{
+ /* -- FPGA: Reset Control Register (32bit R/W) (Offset: 0x14) --
+ * Bit 7, WTCHDG_EN: When set to 1, the watchdog timer is enabled.
+ * Once enabled, it cannot be disabled. The watchdog can be
+ * kicked by performing any write access to the reset
+ * control register (this register).
+ * Bit 8-11, WTCHDG_TIMEOUT_SEC: Sets the watchdog timeout value in
+ * seconds. Valid ranges are 1 to 15 seconds. The value can
+ * be modified dynamically.
+ */
+ unsigned reset = in_be32(pikawdt_private.fpga + 0x14);
+ /* enable with max timeout - 15 seconds */
+ reset |= (1 << 7) + (WDT_HW_TIMEOUT << 8);
+ out_be32(pikawdt_private.fpga + 0x14, reset);
+}
+
+/*
+ * Timer tick
+ */
+static void pikawdt_ping(unsigned long data)
+{
+ if (time_before(jiffies, pikawdt_private.next_heartbeat) ||
+ (!nowayout && !pikawdt_private.open)) {
+ pikawdt_reset();
+ mod_timer(&pikawdt_private.timer, jiffies + WDT_TIMEOUT);
+ } else
+ printk(KERN_CRIT PFX "I will reset your machine !\n");
+}
+
+
+static void pikawdt_keepalive(void)
+{
+ pikawdt_private.next_heartbeat = jiffies + heartbeat * HZ;
+}
+
+static void pikawdt_start(void)
+{
+ pikawdt_keepalive();
+ mod_timer(&pikawdt_private.timer, jiffies + WDT_TIMEOUT);
+}
+
+/*
+ * Watchdog device is opened, and watchdog starts running.
+ */
+static int pikawdt_open(struct inode *inode, struct file *file)
+{
+ /* /dev/watchdog can only be opened once */
+ if (test_and_set_bit(0, &pikawdt_private.open))
+ return -EBUSY;
+
+ pikawdt_start();
+
+ return nonseekable_open(inode, file);
+}
+
+/*
+ * Close the watchdog device.
+ */
+static int pikawdt_release(struct inode *inode, struct file *file)
+{
+ /* stop internal ping */
+ if (!pikawdt_private.expect_close)
+ del_timer(&pikawdt_private.timer);
+
+ clear_bit(0, &pikawdt_private.open);
+ pikawdt_private.expect_close = 0;
+ return 0;
+}
+
+/*
+ * Pat the watchdog whenever device is written to.
+ */
+static ssize_t pikawdt_write(struct file *file, const char __user *data,
+ size_t len, loff_t *ppos)
+{
+ if (!len)
+ return 0;
+
+ /* Scan for magic character */
+ if (!nowayout) {
+ size_t i;
+
+ pikawdt_private.expect_close = 0;
+
+ for (i = 0; i < len; i++) {
+ char c;
+ if (get_user(c, data + i))
+ return -EFAULT;
+ if (c == 'V') {
+ pikawdt_private.expect_close = 42;
+ break;
+ }
+ }
+ }
+
+ pikawdt_keepalive();
+
+ return len;
+}
+
+/*
+ * Handle commands from user-space.
+ */
+static long pikawdt_ioctl(struct file *file,
+ unsigned int cmd, unsigned long arg)
+{
+ void __user *argp = (void __user *)arg;
+ int __user *p = argp;
+ int new_value;
+
+ switch (cmd) {
+ case WDIOC_GETSUPPORT:
+ return copy_to_user(argp, &ident, sizeof(ident)) ? -EFAULT : 0;
+
+ case WDIOC_GETSTATUS:
+ return put_user(0, p);
+
+ case WDIOC_GETBOOTSTATUS:
+ return put_user(pikawdt_private.bootstatus, p);
+
+ case WDIOC_KEEPALIVE:
+ pikawdt_keepalive();
+ return 0;
+
+ case WDIOC_SETTIMEOUT:
+ if (get_user(new_value, p))
+ return -EFAULT;
+
+ heartbeat = new_value;
+ pikawdt_keepalive();
+
+ return put_user(new_value, p); /* return current value */
+
+ case WDIOC_GETTIMEOUT:
+ return put_user(heartbeat, p);
+ }
+ return -ENOTTY;
+}
+
+
+static const struct file_operations pikawdt_fops = {
+ .owner = THIS_MODULE,
+ .llseek = no_llseek,
+ .open = pikawdt_open,
+ .release = pikawdt_release,
+ .write = pikawdt_write,
+ .unlocked_ioctl = pikawdt_ioctl,
+};
+
+static struct miscdevice pikawdt_miscdev = {
+ .minor = WATCHDOG_MINOR,
+ .name = "watchdog",
+ .fops = &pikawdt_fops,
+};
+
+static int __init pikawdt_init(void)
+{
+ struct device_node *np;
+ void __iomem *fpga;
+ static u32 post1;
+ int ret;
+
+ np = of_find_compatible_node(NULL, NULL, "pika,fpga");
+ if (np == NULL) {
+ printk(KERN_ERR PFX "Unable to find fpga.\n");
+ return -ENOENT;
+ }
+
+ pikawdt_private.fpga = of_iomap(np, 0);
+ of_node_put(np);
+ if (pikawdt_private.fpga == NULL) {
+ printk(KERN_ERR PFX "Unable to map fpga.\n");
+ return -ENOMEM;
+ }
+
+ ident.firmware_version = in_be32(pikawdt_private.fpga + 0x1c) & 0xffff;
+
+ /* POST information is in the sd area. */
+ np = of_find_compatible_node(NULL, NULL, "pika,fpga-sd");
+ if (np == NULL) {
+ printk(KERN_ERR PFX "Unable to find fpga-sd.\n");
+ ret = -ENOENT;
+ goto out;
+ }
+
+ fpga = of_iomap(np, 0);
+ of_node_put(np);
+ if (fpga == NULL) {
+ printk(KERN_ERR PFX "Unable to map fpga-sd.\n");
+ ret = -ENOMEM;
+ goto out;
+ }
+
+ /* -- FPGA: POST Test Results Register 1 (32bit R/W) (Offset: 0x4040) --
+ * Bit 31, WDOG: Set to 1 when the last reset was caused by a watchdog
+ * timeout.
+ */
+ post1 = in_be32(fpga + 0x40);
+ if (post1 & 0x80000000)
+ pikawdt_private.bootstatus = WDIOF_CARDRESET;
+
+ iounmap(fpga);
+
+ setup_timer(&pikawdt_private.timer, pikawdt_ping, 0);
+
+ ret = misc_register(&pikawdt_miscdev);
+ if (ret) {
+ printk(KERN_ERR PFX "Unable to register miscdev.\n");
+ goto out;
+ }
+
+ printk(KERN_INFO PFX "initialized. heartbeat=%d sec (nowayout=%d)\n",
+ heartbeat, nowayout);
+ return 0;
+
+out:
+ iounmap(pikawdt_private.fpga);
+ return ret;
+}
+
+static void __exit pikawdt_exit(void)
+{
+ misc_deregister(&pikawdt_miscdev);
+
+ iounmap(pikawdt_private.fpga);
+}
+
+module_init(pikawdt_init);
+module_exit(pikawdt_exit);
+
+MODULE_AUTHOR("Sean MacLennan <smaclennan@pikatech.com>");
+MODULE_DESCRIPTION("PIKA FPGA based Watchdog Timer");
+MODULE_LICENSE("GPL");
+MODULE_ALIAS_MISCDEV(WATCHDOG_MINOR);
+
diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c
index 2bc0d4d..a2d2e8e 100644
--- a/drivers/watchdog/wm8350_wdt.c
+++ b/drivers/watchdog/wm8350_wdt.c
@@ -279,7 +279,7 @@ static struct miscdevice wm8350_wdt_miscdev = {
.fops = &wm8350_wdt_fops,
};
-static int wm8350_wdt_probe(struct platform_device *pdev)
+static int __devinit wm8350_wdt_probe(struct platform_device *pdev)
{
struct wm8350 *wm8350 = platform_get_drvdata(pdev);
@@ -296,7 +296,7 @@ static int wm8350_wdt_probe(struct platform_device *pdev)
return misc_register(&wm8350_wdt_miscdev);
}
-static int __exit wm8350_wdt_remove(struct platform_device *pdev)
+static int __devexit wm8350_wdt_remove(struct platform_device *pdev)
{
misc_deregister(&wm8350_wdt_miscdev);
@@ -305,7 +305,7 @@ static int __exit wm8350_wdt_remove(struct platform_device *pdev)
static struct platform_driver wm8350_wdt_driver = {
.probe = wm8350_wdt_probe,
- .remove = wm8350_wdt_remove,
+ .remove = __devexit_p(wm8350_wdt_remove),
.driver = {
.name = "wm8350-wdt",
},
diff --git a/drivers/xen/events.c b/drivers/xen/events.c
index eb0dfde..3141e14 100644
--- a/drivers/xen/events.c
+++ b/drivers/xen/events.c
@@ -26,6 +26,7 @@
#include <linux/irq.h>
#include <linux/module.h>
#include <linux/string.h>
+#include <linux/bootmem.h>
#include <asm/ptrace.h>
#include <asm/irq.h>
@@ -75,7 +76,14 @@ enum {
static int evtchn_to_irq[NR_EVENT_CHANNELS] = {
[0 ... NR_EVENT_CHANNELS-1] = -1
};
-static unsigned long cpu_evtchn_mask[NR_CPUS][NR_EVENT_CHANNELS/BITS_PER_LONG];
+struct cpu_evtchn_s {
+ unsigned long bits[NR_EVENT_CHANNELS/BITS_PER_LONG];
+};
+static struct cpu_evtchn_s *cpu_evtchn_mask_p;
+static inline unsigned long *cpu_evtchn_mask(int cpu)
+{
+ return cpu_evtchn_mask_p[cpu].bits;
+}
static u8 cpu_evtchn[NR_EVENT_CHANNELS];
/* Reference counts for bindings to IRQs. */
@@ -115,7 +123,7 @@ static inline unsigned long active_evtchns(unsigned int cpu,
unsigned int idx)
{
return (sh->evtchn_pending[idx] &
- cpu_evtchn_mask[cpu][idx] &
+ cpu_evtchn_mask(cpu)[idx] &
~sh->evtchn_mask[idx]);
}
@@ -125,11 +133,11 @@ static void bind_evtchn_to_cpu(unsigned int chn, unsigned int cpu)
BUG_ON(irq == -1);
#ifdef CONFIG_SMP
- irq_to_desc(irq)->affinity = cpumask_of_cpu(cpu);
+ cpumask_copy(irq_to_desc(irq)->affinity, cpumask_of(cpu));
#endif
- __clear_bit(chn, cpu_evtchn_mask[cpu_evtchn[chn]]);
- __set_bit(chn, cpu_evtchn_mask[cpu]);
+ __clear_bit(chn, cpu_evtchn_mask(cpu_evtchn[chn]));
+ __set_bit(chn, cpu_evtchn_mask(cpu));
cpu_evtchn[chn] = cpu;
}
@@ -142,12 +150,12 @@ static void init_evtchn_cpu_bindings(void)
/* By default all event channels notify CPU#0. */
for_each_irq_desc(i, desc) {
- desc->affinity = cpumask_of_cpu(0);
+ cpumask_copy(desc->affinity, cpumask_of(0));
}
#endif
memset(cpu_evtchn, 0, sizeof(cpu_evtchn));
- memset(cpu_evtchn_mask[0], ~0, sizeof(cpu_evtchn_mask[0]));
+ memset(cpu_evtchn_mask(0), ~0, sizeof(cpu_evtchn_mask(0)));
}
static inline unsigned int cpu_from_evtchn(unsigned int evtchn)
@@ -822,6 +830,10 @@ static struct irq_chip xen_dynamic_chip __read_mostly = {
void __init xen_init_IRQ(void)
{
int i;
+ size_t size = nr_cpu_ids * sizeof(struct cpu_evtchn_s);
+
+ cpu_evtchn_mask_p = alloc_bootmem(size);
+ BUG_ON(cpu_evtchn_mask_p == NULL);
init_evtchn_cpu_bindings();
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index 9b91617..e7e83b6 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -100,7 +100,7 @@ static void do_suspend(void)
/* XXX use normal device tree? */
xenbus_suspend();
- err = stop_machine(xen_suspend, &cancelled, &cpumask_of_cpu(0));
+ err = stop_machine(xen_suspend, &cancelled, cpumask_of(0));
if (err) {
printk(KERN_ERR "failed to start xen_suspend: %d\n", err);
goto out;
diff --git a/drivers/zorro/.gitignore b/drivers/zorro/.gitignore
new file mode 100644
index 0000000..34f980b
--- /dev/null
+++ b/drivers/zorro/.gitignore
@@ -0,0 +1,2 @@
+devlist.h
+gen-devlist
diff --git a/drivers/zorro/zorro-sysfs.c b/drivers/zorro/zorro-sysfs.c
index 5290552..1d2a772e 100644
--- a/drivers/zorro/zorro-sysfs.c
+++ b/drivers/zorro/zorro-sysfs.c
@@ -77,17 +77,21 @@ static struct bin_attribute zorro_config_attr = {
.read = zorro_read_config,
};
-void zorro_create_sysfs_dev_files(struct zorro_dev *z)
+int zorro_create_sysfs_dev_files(struct zorro_dev *z)
{
struct device *dev = &z->dev;
+ int error;
/* current configuration's attributes */
- device_create_file(dev, &dev_attr_id);
- device_create_file(dev, &dev_attr_type);
- device_create_file(dev, &dev_attr_serial);
- device_create_file(dev, &dev_attr_slotaddr);
- device_create_file(dev, &dev_attr_slotsize);
- device_create_file(dev, &dev_attr_resource);
- sysfs_create_bin_file(&dev->kobj, &zorro_config_attr);
+ if ((error = device_create_file(dev, &dev_attr_id)) ||
+ (error = device_create_file(dev, &dev_attr_type)) ||
+ (error = device_create_file(dev, &dev_attr_serial)) ||
+ (error = device_create_file(dev, &dev_attr_slotaddr)) ||
+ (error = device_create_file(dev, &dev_attr_slotsize)) ||
+ (error = device_create_file(dev, &dev_attr_resource)) ||
+ (error = sysfs_create_bin_file(&dev->kobj, &zorro_config_attr)))
+ return error;
+
+ return 0;
}
diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c
index dff16d9..a1585d6 100644
--- a/drivers/zorro/zorro.c
+++ b/drivers/zorro/zorro.c
@@ -130,6 +130,7 @@ static int __init zorro_init(void)
{
struct zorro_dev *z;
unsigned int i;
+ int error;
if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(ZORRO))
return 0;
@@ -140,7 +141,11 @@ static int __init zorro_init(void)
/* Initialize the Zorro bus */
INIT_LIST_HEAD(&zorro_bus.devices);
strcpy(zorro_bus.dev.bus_id, "zorro");
- device_register(&zorro_bus.dev);
+ error = device_register(&zorro_bus.dev);
+ if (error) {
+ pr_err("Zorro: Error registering zorro_bus\n");
+ return error;
+ }
/* Request the resources */
zorro_bus.num_resources = AMIGAHW_PRESENT(ZORRO3) ? 4 : 2;
@@ -160,15 +165,19 @@ static int __init zorro_init(void)
zorro_name_device(z);
z->resource.name = z->name;
if (request_resource(zorro_find_parent_resource(z), &z->resource))
- printk(KERN_ERR "Zorro: Address space collision on device %s "
- "[%lx:%lx]\n",
- z->name, (unsigned long)zorro_resource_start(z),
- (unsigned long)zorro_resource_end(z));
+ pr_err("Zorro: Address space collision on device %s %pR\n",
+ z->name, &z->resource);
sprintf(z->dev.bus_id, "%02x", i);
z->dev.parent = &zorro_bus.dev;
z->dev.bus = &zorro_bus_type;
- device_register(&z->dev);
- zorro_create_sysfs_dev_files(z);
+ error = device_register(&z->dev);
+ if (error) {
+ pr_err("Zorro: Error registering device %s\n", z->name);
+ continue;
+ }
+ error = zorro_create_sysfs_dev_files(z);
+ if (error)
+ dev_err(&z->dev, "Error creating sysfs files\n");
}
/* Mark all available Zorro II memory */
diff --git a/drivers/zorro/zorro.h b/drivers/zorro/zorro.h
index 5c91ada..b682d5c 100644
--- a/drivers/zorro/zorro.h
+++ b/drivers/zorro/zorro.h
@@ -1,4 +1,4 @@
extern void zorro_name_device(struct zorro_dev *z);
-extern void zorro_create_sysfs_dev_files(struct zorro_dev *z);
+extern int zorro_create_sysfs_dev_files(struct zorro_dev *z);
diff --git a/firmware/Makefile b/firmware/Makefile
index ea1d28f..466106f 100644
--- a/firmware/Makefile
+++ b/firmware/Makefile
@@ -78,7 +78,8 @@ fw-shipped- += keyspan/mpr.fw keyspan/usa18x.fw keyspan/usa19.fw \
keyspan/usa28.fw keyspan/usa28xa.fw keyspan/usa28xb.fw \
keyspan/usa28x.fw keyspan/usa49w.fw keyspan/usa49wlc.fw
endif
-fw-shipped-$(CONFIG_USB_SERIAL_TI) += ti_3410.fw ti_5052.fw
+fw-shipped-$(CONFIG_USB_SERIAL_TI) += ti_3410.fw ti_5052.fw \
+ mts_cdma.fw mts_gsm.fw mts_edge.fw
fw-shipped-$(CONFIG_USB_SERIAL_EDGEPORT) += edgeport/boot.fw edgeport/boot2.fw \
edgeport/down.fw edgeport/down2.fw
fw-shipped-$(CONFIG_USB_SERIAL_EDGEPORT_TI) += edgeport/down3.bin
diff --git a/firmware/WHENCE b/firmware/WHENCE
index 8b56513..524113f 100644
--- a/firmware/WHENCE
+++ b/firmware/WHENCE
@@ -191,7 +191,7 @@ Original licence information: None
--------------------------------------------------------------------------
-Driver: tu_usb_3410_5052 -- USB TI 3410/5052 serial device
+Driver: ti_usb_3410_5052 -- USB TI 3410/5052 serial device
File: ti_3410.fw
Info: firmware 9/10/04 FW3410_Special_StartWdogOnStartPort
@@ -206,6 +206,20 @@ Found in hex form in kernel source.
--------------------------------------------------------------------------
+Driver: ti_usb_3410_5052 -- Multi-Tech USB cell modems
+
+File: mts_cdma.fw
+File: mts_gsm.fw
+File: mts_edge.fw
+
+Licence: "all firmware components are redistributable in binary form"
+ per support@multitech.com
+ Copyright (C) 2005 Multi-Tech Systems, Inc.
+
+Found in hex form in ftp://ftp.multitech.com/wireless/wireless_linux.zip
+
+--------------------------------------------------------------------------
+
Driver: whiteheat -- USB ConnectTech WhiteHEAT serial device
File: whiteheat.fw
diff --git a/firmware/mts_cdma.fw.ihex b/firmware/mts_cdma.fw.ihex
new file mode 100644
index 0000000..f6ad0cb
--- /dev/null
+++ b/firmware/mts_cdma.fw.ihex
@@ -0,0 +1,867 @@
+:1000000014360002001E021AF9FFFFFFFFFF023341
+:100010001DFFFFFFFFFFFFFFFFFFFFFFFFFF02339B
+:10002000C87581CE90FDE88583A012353CEC4D600B
+:100030007378AB8003760018B89CFA787F800376DB
+:100040000018B865FA78208003760018B820FA788E
+:10005000208003760018B81FFA90FDDDAE83AF82D2
+:1000600090FBF81200AA6005E4F0A380F690FDE88A
+:10007000A88290FDE8A982E8696005E4F20880F7AB
+:100080009001081200B390010C1200B390011012FD
+:1000900000B39001141200D190011A1200D1900106
+:1000A000201200D175D00012341A020126EF6582A9
+:1000B0007003EE658322E493F8740193F97402935C
+:1000C000FE740393F5828E83E869700122E493F64F
+:1000D000A30880F4E493FC740193FD740293FE740E
+:1000E0000393FF740493F8740593F58288831200D8
+:1000F000AA700122E493A3A883A9828C838D82F045
+:10010000A3AC83AD828883898280E32121049B8014
+:1001100080049BACAE049BFDE8049D049DFBF304AE
+:10012000A2049DFBF30502050280FED0F030F00929
+:1001300020F303F68010F7800D30F10920F303F26D
+:100140008004F38001F020F404FCD0E0CC22CCC089
+:10015000E0120163020154BC0005D0F0ACF022C3F0
+:1001600013DCFC02012ABF0009ED258275F001F8BD
+:10017000E622BF010FED2582F582EE3583F583750A
+:10018000F004E022ED258275F002F8E222D083D05F
+:1001900082F5F0C3E493A3C5F095F0C0E0C3D0F0BE
+:1001A000E493A395F04012A3A3C3E5F033500205F6
+:1001B000832582F58250020583740193C0E0E493A5
+:1001C000C0E022D083D082F5F0E4937009740193EB
+:1001D0007004A3A3800C74029365F06005A3A3A32D
+:1001E00080E7740193C0E0E493C0E022120264024D
+:1001F00001FB1202B80201FB1202DC0201FB30E03B
+:100200000720E302E622E72230E10720E302E222B0
+:10021000E32230E202E022E493221202DC02022313
+:100220001202B8020223ABF012022DCBC5F0CB2292
+:1002300030E01020E306E6F5F008E622E7F5F009E5
+:10024000E7192230E11020E306E2F5F008E222E3AC
+:10025000F5F009E3192230E206E0F5F0A3E022E42C
+:1002600093F5F074019322BB0003740922BB0107CC
+:1002700089828A83740422BB020789828A8374106C
+:1002800022740A22020284BB0007E92582F8740165
+:1002900022BB010DE92582F582EA3583F5837404DA
+:1002A00022BB020DE92582F582EA3583F5837410BD
+:1002B00022E92582F87402220202B8BF0005EDF897
+:1002C000740122BF01078D828E83740422BF02074E
+:1002D0008D828E83741022EDF87402220202DCBF3C
+:1002E0000007ED2582F8740122BF010DED2582F58E
+:1002F00082EE3583F583740422BF020DED2582F56D
+:1003000082EE3583F583741022ED2582F874022283
+:10031000020310C0E0120264020328C0E01202B817
+:10032000020328C0E01202DC02032830E00B20E3C5
+:1003300004D0E0F622D0E0F72230E10B20E304D035
+:10034000E0F222D0E0F322D0E0F022C9CDC9CACE3B
+:10035000CACBCFCB12035BEDF9EEFAEFFB22BB0069
+:100360002FBF000AFAEDF8E7F60809DAFA22BF0112
+:10037000128D828E83F802037809A3E7F0D8FA225F
+:10038000020383FAEDF8E7F20809DAFA2202038D94
+:10039000BB014DBF001489828A83F9EDF802039FE7
+:1003A00008A3E0F6D9FA220203B0BF01228D828EA3
+:1003B00083FB08C9C582C9CAC583CAE0A3C9C5826F
+:1003C000C9CAC583CAF0A3DBEAD8E8220203D38DE9
+:1003D000828E83F9EDF8E0F208A3D9FA220203DD58
+:1003E000BB024DBF001289828A83F9EDF80203EF48
+:1003F00008A3E493F6D9F922BF01238D828E83FBF3
+:1004000008C9C582C9CAC583CAE493A3C9C582C93C
+:10041000CAC583CAF0A3DBE9D8E722020422898295
+:100420008A83F9EDF8E493F208A3D9F922020433A0
+:10043000BF000DFAEDF8E3F60809DAFA2202043DEE
+:10044000BF01128D828E83F802044A09A3E3F0D81B
+:10045000FA22020455FAEDF8E3F20809DAFA220268
+:10046000045FE6FB08E6FA08E6F904F618700106F0
+:1004700022E6FF08E6FE08E6FD22EFF0A3EEF0A379
+:10048000EDF022EBF0A3EAF0A3E9F022E0FFA3E015
+:10049000FEA3E0FD22E0FBA3E0FAA3E0F9220000C6
+:1004A00000000000000502006105710026059800AB
+:1004B000330A0900610A750066154400610CF900F1
+:1004C0006109A9006109E000610DC000610BF10044
+:1004D000610A1C00610A510061173C0033174F008C
+:1004E000341E1400431EBF0044202C0044201A0078
+:1004F000471EE600471F8B004D1FDC004F1F080002
+:100500005832A800617CCC7DFF121CC52290FFFCF4
+:10051000E020E72DC2AFAE59AF58755A20E55A1406
+:10052000C55A6019E4FE7F05EE4FCE24FFCECF34CE
+:10053000FFCF6007E490FF92F080ED80E08E598F4E
+:10054000582212050A7D077CB71232C47D0F7C6EDB
+:100550001232DE789D7A06E4F608DAFC7A06120595
+:10056000CD7C03120E55122168E4FEFF7C0F12327F
+:100570004DD2A822123138E490FC38F090FFF0E020
+:1005800030E408740190FC39F08005E490FC39F007
+:100590007D0A7C001225461231BB2212313890FCB4
+:1005A00039E014700E90FFF0E04410F07C0012254A
+:1005B000DF801990FC39E0700E90FFF0E054EFF00E
+:1005C0007C001225DF80057C171225DF1231BB224B
+:1005D00090FFF0E054ABF090FFF0E04420F0228C6C
+:1005E000378D367882EDF608ECF6EDFEECFD7F01F6
+:1005F0009000051201F57880F67882E6FD08E6FCA9
+:10060000EDFEECFD7F019000041201F5540FFC7D1E
+:100610008012176D7880E6700DAD3AAE39AF38E4D0
+:100620001203187C082290FFF0E054FEF090FFF0D7
+:10063000E054FDF0801E7882E6FD08E6FCEDFEEC5D
+:10064000FD7F0190000812021725E0440190FFF39E
+:10065000F00206D97882E6FD08E6FCEDFEECFD7FAF
+:100660000190000612021754FE90FFF3F0802B78E1
+:1006700082E6FD08E6FCEDFEECFD7F01900008122D
+:100680000217FAEB90FFF1F01208C8400DAD3AAE38
+:1006900039AF38E41203187C18227882E6FD08E6A8
+:1006A000FCEDFEECFD7F0190000812021790FFF1B7
+:1006B000F01208C8400DAD3AAE39AF38E412031855
+:1006C0007C18227882E6FD08E6FCEDFEECFD7F0159
+:1006D000900006120217440190FFF3F07883E6249D
+:1006E00003F618E63400F67880E624FE500990FF01
+:1006F000F0E054FDF0800790FFF0E04402F0E49059
+:10070000FFF1F0788176007880E624FFFCE434FF86
+:10071000FD7881E67F00FEECD39EEF6480CD64809F
+:100720009D402F1208AD400F7881E6AD3AAE39AF4B
+:10073000381203187C182290FFF2E0FC788286833E
+:10074000088682ECF0788106A37882A68308A682C8
+:1007500080B51208AD400F7881E6AD3AAE39AF38BA
+:100760001203187C182290FFF2E0FC78828683083E
+:100770008682ECF07880E6AD3AAE39AF38120318D5
+:100780007C00228C378D367882EDF608ECF6EDFE93
+:10079000ECFD7F019000051201F57881F67882E684
+:1007A000FD08E6FCEDFEECFD7F019000041201F572
+:1007B000540FFC7D8112176D7881E670037C08224E
+:1007C00090FFF0E054FEF090FFF0E054FDF0801B4D
+:1007D0007882E6FD08E6FCEDFEECFD7F0190000866
+:1007E00012021725E090FFF3F0805B7882E6FD08A7
+:1007F000E6FCEDFEECFD7F0190000612021754FEB0
+:1008000090FFF3F080217882E6FD08E6FCEDFEEC37
+:10081000FD7F01900008120217FAEB90FFF1F01231
+:1008200008C840037C18227882E6FD08E6FCEDFE4D
+:10083000ECFD7F0190000812021790FFF1F0120802
+:10084000C840037C18227883E6240AF618E63400B0
+:10085000F6788076007881E624FFFCE434FFFD78AA
+:1008600080E67F00FEECD39EEF6480CD64809D40E7
+:100870002178828683088682E090FFF1F01208C812
+:1008800040037C1822788006788306E618700106FB
+:1008900080C390FFF0E04401F0788286830886826E
+:1008A000E090FFF1F01208C840037C18227C00227F
+:1008B00090FFF0E020E71290FFF0E030E50990FFB4
+:1008C000F0E04420F0C32280E7D32290FFF0E02044
+:1008D000E31290FFF0E030E50990FFF0E04420F0F3
+:1008E000C32280E7D3228C428D417C00ED54F0FD81
+:1008F000EC7003ED64307005753E038003753E04B3
+:10090000AC3E120F72758300858340E541540FF5AC
+:100910003FE5407004E53F64037035E53E24FD7516
+:10092000F00AA42402F582E434FCF583E030E60505
+:100930001210598019E53E249DF8E654FBF678A97B
+:10094000E62405F58218E63400F583740FF080592B
+:10095000E5407004E53F64047048E53E24FD75F011
+:100960000AA42402F582E434FCF583E030E507AC08
+:1009700042AD41121C5AE54230E21578ADE630E056
+:100980000F78ADE630E109E4FF04FE7C0412324D3D
+:1009900078A9E62406F58218E63400F583740FF092
+:1009A0008007E4FC7DEE121C5AC203221231381279
+:1009B0000F7278A9E62406F58218E63400F583E084
+:1009C00090FC38F078A9E62405F58218E63400F5A5
+:1009D00083E090FC39F0C2037D027C0012254612B0
+:1009E00031BB221231387895ECF6EC249DF8E630D4
+:1009F000E1077C131225DF800F90FC39E0FD78952C
+:100A0000E6FC1213EF1225DF1231BB2212313878C7
+:100A100095ECF67D00120F121225DF1231BB221267
+:100A200031387895ECF6EC249DF8E630E2077C133B
+:100A30001225DF801B7895E6249DF8E620E1077CEF
+:100A4000121225DF800A7895E6FC1214131225DFB6
+:100A50001231BB221231387895ECF6EC249DF8E681
+:100A600020E2077C111225DF800A7895E6FC12153A
+:100A7000141225DF1231BB221231387895ECF612B0
+:100A80000F7278A9E62409F58218E63400F583E0B0
+:100A900090FC3FF078A9E6240AF58218E63400F5C8
+:100AA00083E090FC40F078A9E62403F58218E63450
+:100AB00000F583E0FC78A9E62404F58218E634000A
+:100AC000F583E0F56278A9E62402F58218E63400A1
+:100AD000F583E0F5638C61E4EC333354017895F6EB
+:100AE0006008E56230E1037895067895E690FC4170
+:100AF000F078A7E62402F58218E63400F583E0FDDD
+:100B0000A3E0540CFCED54E68C65F564E56130E53A
+:100B100003436501E56220E50EE561547F7008E559
+:100B20006120E703436502E56130E303436510E5B7
+:100B30006130E203436520E561540360034365408F
+:100B4000E56130E103436580E56130E4034364011E
+:100B5000E56130E603436408E56220E40EE5615494
+:100B60007F7008E56120E7034364105365FB53641D
+:100B7000F9AD64E56590FC3ACDF0A3CDF0E56330C6
+:100B8000E30DE5635430C4540F90FC3DF08005E460
+:100B900090FC3DF0E563540390FC3CF0E5635404A5
+:100BA000C31390FC3EF090FC3CE0700E7D357EFC63
+:100BB0007F01740190000912014B78A9E62408F521
+:100BC0008218E63400F583E07C00FD78A9E624076E
+:100BD000F58218E63400F583E07F004CFEEF4D907F
+:100BE000FC38F0A3CEF0CEC2037D0A7C001225466D
+:100BF0001231BB221231387895ECF6789A760108DA
+:100C000076FC0876387897760C789A12046E120281
+:100C10001D7898CBF6CB08F67F00EF24EA401FE45E
+:100C2000EF25E090357EFD93CD04937899667003AF
+:100C3000ED186670067897760080030F80DC789652
+:100C4000EFF6789A12046E9000021202177898CB91
+:100C5000F6CB08F65404CB54064B60047897760B19
+:100C60007899E630E313789A12046E900005120129
+:100C7000F524FB50047897760D7899E654C07D00F2
+:100C800064C04D70047897760B789A12046E9000C9
+:100C9000041201F524FC50047897760F789A120418
+:100CA0006E9000061201F524FD50047897760E78B8
+:100CB0009A12046E9000091201F524FD50047897F1
+:100CC000760A7897E6702A7895E6FC120F72789A81
+:100CD00012046E78A7E6F978A6E6FA7B01740A7822
+:100CE00000120348C2037895E6FC1211157897ECC0
+:100CF000F67897E6FC1225DF1231BB2212313878E4
+:100D000095ECF6120F727895E624FD75F00AA4248E
+:100D100014F582E434FCF583AC82AD8378A6868337
+:100D2000088682ECF9EDFA7B0A78011203B0C2035F
+:100D30007895E6FC1211151231BB228D2B8C2AED11
+:100D400060407527017529487528FFE52A24FDFCB8
+:100D5000E434FFFDEC7C0325E0CD33CDDCF9FCE58C
+:100D6000292CF529E5283DF528AD29AE28AF2774B3
+:100D7000809000061203207480900002120320125B
+:100D80000FC5E52B14603B7527017529087528FFF1
+:100D9000E52A24FDFCE434FFFDEC7C0325E0CD33A3
+:100DA000CDDCF9FCE5292CF529E5283DF528AD2910
+:100DB000AE28AF27E4900006120320E49000021250
+:100DC0000320221231387895ECF6EC249DF8E630B9
+:100DD000E2097895E6FC121514D2007895E6FC122B
+:100DE0000F727896760090FC39E030E704789676BA
+:100DF000017896E6FD7895E6FC120D38C2033000C6
+:100E0000077895E6FC1214137C001225DF1231BB23
+:100E10002278A9E62404F58218E63400F583E0443C
+:100E200001F078A9E62404F58218E63400F583E0A1
+:100E300030E00280ED78A9E6240BF58218E6340054
+:100E4000F583E054F8F078A9E62402F58218E63438
+:100E500000F583E04480F022C2038C58120F7278B0
+:100E6000A6868308868279AF7A357B0A78011203D9
+:100E7000FE120E0EAC587D02120D38C203AC581291
+:100E80001115228D538E528F518C50120F72754F47
+:100E90000078A9E62405F58218E63400F583E02001
+:100EA000E41FE54F24F64019054FC2037C181232A7
+:100EB000FB90FF93E04401F0B2B3AC50120F72808C
+:100EC000D078A9E62405F58218E63400F583E02001
+:100ED000E405C2037C022278A9E62405F58218E61F
+:100EE0003400F583E0540F601678A9E62405F582F6
+:100EF00018E63400F583E0540FF0C2037C01227839
+:100F0000A88683088682E0AD53AE52AF5112031813
+:100F1000C2037C00228D318C30121514E531600F34
+:100F2000E530B4030A7C0112250E7C8112250EAC3B
+:100F300030120F72E531601A78AA8683088682E043
+:100F400054E7F0A3A3A3A3E054E7F0AC307D021272
+:100F50000D3878A6868308868279B97A357B0A7837
+:100F6000011203FEC203E530249DF8E654FDF6AC01
+:100F700030121115228C2630030512329A80F87C2B
+:100F80000A1231ADD203E52624FD78A3F670077866
+:100F9000AA76FF0876E078A3E67D007C0425E0CD04
+:100FA00033CDDCF9FC24A078A9F6ED34FF18F678EF
+:100FB000A3E675F00AA42400FCE434FCFD78A6ED59
+:100FC000F608ECF61232462278A9E62402F58218D9
+:100FD000E63400F583E030E72278A9E62402F582C2
+:100FE00018E63400F583E0547FF078A9E62402F592
+:100FF0008218E63400F583E04480F02278AA8683E4
+:10100000088682E0547FF0AD83E5822404FCE43D51
+:101010008C82F583E0547FF078A9E6240BF58218E2
+:10102000E63400F583E054F8F078ABE62401F5826D
+:1010300018E63400F583E04403F078ABE62405F5C8
+:101040008218E63400F583E04403F078A9E624052D
+:10105000F58218E63400F583740FF02278AA8683AF
+:10106000088682E0543FF0AD83E5822404FCE43D31
+:101070008C82F583E0543FF078A3E624A4F8E6FCE4
+:1010800078ABE62401F58218E63400F583ECF078BD
+:10109000A3E624A4F8E6FC78ABE62405F58218E67E
+:1010A0003400F583ECF078A9E6240BF58218E634D9
+:1010B00000F583E054FB4402F52678A7E62402F508
+:1010C0008218E63400F583E030E50343260178A971
+:1010D000E62405F58218E63400F583E030E00312DB
+:1010E0000FC5E526FC78A9E6240BF58218E6340046
+:1010F000F583ECF078A9E62405F58218E63400F5CE
+:1011000083740FF078AA8683088682E04480F0A377
+:10111000A3A3A3E04480F0228C2A120F7278A7E6E2
+:101120002408F58218E63400F583E0FC78A9E6246B
+:101130000AF58218E63400F583ECF078A7E6240778
+:10114000F58218E63400F583E0FC78A9E62409F579
+:101150008218E63400F583ECF078A6868308868250
+:10116000E0FDA3E0FCEDFE78A9E62408F58218E690
+:101170003400F583EEF0ECFE78A9E62407F582183A
+:10118000E63400F583EEF08C298D28C3EC9405ED50
+:10119000940C400575277C8033D3E5299401E5281C
+:1011A0009403400575273C8023D3E5299481E528E5
+:1011B000940140057527188013D3E5299460E5282C
+:1011C0009400400575270C8003752708AF27E4EFCE
+:1011D000547C4483FF8F27E527FC78ABE62401F598
+:1011E0008218E63400F583ECF0E527FC78ABE624C2
+:1011F00005F58218E63400F583ECF0E527FC78A3CA
+:10120000E624A4F8ECF678A9E62402F58218E63480
+:1012100000F583E0F52778A7E62402F58218E63486
+:1012200000F583A3E030E3175327C778A7E624052A
+:10123000F58218E63400F583E09035AA93422778CA
+:10124000A7E62402F58218E63400F583E030E705CE
+:1012500043274080035327BF5327FB78A7E6240684
+:10126000F58218E63400F583E06003432704532732
+:10127000FC78A7E62404F58218E63400F583E04202
+:1012800027432780E527FC78A9E62402F58218E6A3
+:101290003400F583ECF078A9E62404F58218E634EE
+:1012A00000F583E0F52778A7E62402F58218E634F6
+:1012B00000F583A3E030E1055327DF8003432720B7
+:1012C00078A7E62402F58218E63400F583E030E4DE
+:1012D000055327EF800343271078A7E62409F582FA
+:1012E00018E63400F583E0B40203432702E527FC47
+:1012F00078A9E62404F58218E63400F583ECF0784A
+:10130000A9E62403F58218E63400F583E0F5277892
+:10131000A7E62409F58218E63400F583E07005534A
+:10132000277F800343278078A7E62402F58218E60A
+:101330003400F583A3E030E00543272080035327E2
+:10134000DF78A7E62402F58218E63400F583E03062
+:10135000E30543274080035327BF78A7E62402F51F
+:101360008218E63400F583E030E00543271080035F
+:101370005327EF78A7E62402F58218E63400F583B8
+:10138000A3E030E40543270880035327F778A7E656
+:101390002402F58218E63400F583A3E030E5054326
+:1013A000270480035327FB78A7E62402F58218E67A
+:1013B0003400F583A3E030E605432701800353277B
+:1013C000FE78A7E62402F58218E63400F583A3E050
+:1013D00030E70543270280035327FDE527FC78A962
+:1013E000E62403F58218E63400F583ECF0C2037CB2
+:1013F00000228D278C26ED54031460037C1022E517
+:1014000027547C24FC40037C0B22E526249DF8E62F
+:101410004402F67C00228C30120F72E530249DF8D5
+:10142000E620E24FAC307D02120D38E53024FE4458
+:1014300028FC78AA8683088682ECF0AF83E58224B4
+:1014400004FEE43FFFEC8E828F83F07C038C2CE55E
+:101450002CFC78ABE62401F58218E63400F583EC29
+:10146000F0E52CFC78ABE62405F58218E63400F5AF
+:1014700083ECF0752D01752F48752EFFE53024FDA6
+:10148000FCE434FFFDEC7C0325E0CD33CDDCF9FC3E
+:10149000E52F2CF52FE52E3DF52E78ABE62404F54F
+:1014A0008218E63400F583E054E7F52CAD2FAE2E1C
+:1014B000AF2DE4900002120320E4900006120320F6
+:1014C0001201EF30E503432C10E52CFC78ABE62449
+:1014D00004F58218E63400F583ECF012105978A96F
+:1014E000E62406F58218E63400F583E0C203FCE545
+:1014F00030249DF8E64404F68C2CE530540FC45497
+:10150000F07E00FFEEEF44047D00FFEC4EFCED4F5B
+:10151000FD121CC57C00228C2F120F72120FF9785D
+:10152000AA8683088682E05408F0A3A3A3A3E0540C
+:1015300008F0AC2F7D02120D38C203E52F249DF870
+:10154000E654FBF67C00221231387896ECF6EC2457
+:101550009DF8E630E10A7D007C131225461231BB6E
+:101560007896E6249DF8E64401F67896E6FC120F9C
+:10157000727896E624FD75F00AA42414F582E4340A
+:10158000FCF58378A6E6FA08E6F97B0A78011203EF
+:10159000B078A6868308868279B97A357B0A780185
+:1015A0001203FE120FC5C2037896E6FC12111578DD
+:1015B00095ECF6EC600A7D007C081225461231BBE2
+:1015C0007896E6FC120F7278A9E62404F58218E6F4
+:1015D0003400F583E0441054DFFC78A9E62404F5D8
+:1015E0008218E63400F583ECF07895ECF6C2037CC3
+:1015F000C81232FB7896E6FC120F7278A9E6240432
+:10160000F58218E63400F583E054EFF0C2037CC89D
+:101610001232FB7896E6FC120F7278A9E62404F5E4
+:101620008218E63400F583E04410F0C2037CC8124F
+:1016300032FB7896E6FC120F7278A9E62404F58254
+:1016400018E63400F583E04420F0C2037CF0123247
+:10165000FB7896E6FC120F7278A9E62405F582184D
+:10166000E63400F583E030E415C2037896E64410D2
+:101670007F00FE7C0712324D1231BB02173B78A966
+:10168000E62404F58218E63400F583E054CFF0C276
+:10169000037CC81232FB7896E6FC120F7278A9E63A
+:1016A0002404F58218E63400F583E04430F0C203E8
+:1016B0007CF01232FB7896E6FC120F7278A9E624D1
+:1016C00005F58218E63400F583E030E414C20378AF
+:1016D00096E644107F00FE7C0712324D1231BB802B
+:1016E0005D78A9E62404F58218E63400F583E05419
+:1016F000EFF078A9E62404F58218E63400F583E0DB
+:1017000054DFF07896E624FD75F00AA42414F582DF
+:10171000E434FCF583AC82AD8378A68683088682A8
+:10172000ECF9EDFA7B0A78011203B0C2037896E671
+:10173000FC1211157D007C0B1225461231BB2212C2
+:101740003138E490FC39F07D027C001225461231DC
+:10175000BB221231387C001225DF1231BB22743CCF
+:1017600090FBE0F0743E90FBE0F0E490FC28F02267
+:101770008D358C34ECB401028003D340028028B450
+:1017800002028003D34008A835E625E0F68018B4AD
+:1017900004028003D3400AA835E625E025E0F68060
+:1017A00006A83576008000228C3C8D3BEDFEECFDDA
+:1017B0007F0175660675670090FC29120477120197
+:1017C000EFB480028006D3500302186E90FC2912F9
+:1017D00004899000031201F554F0B430028003D361
+:1017E000405F90FC29120489900008120217FAFD4C
+:1017F000EBFE7F0190FC2C120477EECD9035C3FCFC
+:10180000E493FF740193FEF9EFFA7B01EAFFE9FE2E
+:10181000ECC39EED9F40259035C5E493FD74019384
+:10182000FCEDFEECFD7F01EECDFC90FC2EE0D39CA8
+:1018300090FC2DE09D5005756680803312198C80D8
+:101840002EB460028003D3400BAC3CAD3B1207804A
+:101850008C66801BB41003B34010C3B42003B340A4
+:1018600009C3B440028003D34000756681800080C4
+:1018700075B481028003D3406B90FC2912048990D7
+:1018800000031201F554F0B430028003D3401D90E0
+:10189000FC29120489900008120217FAFDEBFE7F62
+:1018A0000190FC2F1204771218F68036B460028083
+:1018B00003D34013753A67E4F539F538AC3CAD3BDA
+:1018C0001205DC8C66801BB41003B34010C3B42037
+:1018D00003B34009C3B440028003D340007566815E
+:1018E000800080028000E566FC90FC29120489ECEF
+:1018F000900002120320AC672290FC291204899008
+:1019000000041201F5600474018001E4A2E0920178
+:1019100090FC29120489ED2403FD50010E90FC2C4B
+:1019200012047790FC291204899000051201F5F544
+:10193000679000041201F5540FFC7D6712176DE5E6
+:10194000677004756608227566007884760078846E
+:10195000E6C39567503890FC2F1204891201EFFC02
+:1019600090FC2C120489EC12031830010E90FC310B
+:10197000E004F090FC307003E004F078840690FC02
+:101980002EE004F090FC2D7003E004F080C0229063
+:10199000FC2AE0FDA3E0FCEDFEECFD7F01ED240A56
+:1019A000FD50010E90FC3212047790FC291204893C
+:1019B0009000041201F5540FB401028003D34017C4
+:1019C00090FC321204890DED70010E90FC2F120470
+:1019D0007778887601804EB402028003D340199054
+:1019E000FC32120489ED2402FD50010E90FC2F12EE
+:1019F000047778887602802DB404028003D34019DE
+:101A000090FC32120489ED2404FD50010E90FC2F4D
+:101A100012047778887604800CB400028003D340E7
+:101A2000007566082290FC291204899000051201B5
+:101A3000F5F567788576007885E6C39567400302FB
+:101A40001AF4788676007886E6C378889650769081
+:101A5000FC2C1204891201EFFC90FC321204921249
+:101A600001E9F45CFC1201E9F890FC2F120489E80A
+:101A7000C0E01201EFC8D0E0C8584CFC90FC2C121A
+:101A80000489EC1203187887ECF690FC31E004F03E
+:101A900090FC307003E004F009E970010A90FC3218
+:101AA00012048090FC291204899000041201F53080
+:101AB000E40E90FC2EE004F090FC2D7003E004F0A6
+:101AC00078860680817888E6FDE4FEFFEECDFC9006
+:101AD000FC31E02CF090FC30E03DF07888E6FDE44D
+:101AE000FEFFEECDFC90FC34E02CF090FC33E03DAA
+:101AF000F0788506021A347566002222C0E0C0F034
+:101B0000C082C083C0D0E8C0E0E9C0E0EAC0E0EB3A
+:101B1000C0E0ECC0E0EDC0E0EEC0E0EFC0E090FF60
+:101B200092E01201C01B47301B47321B56381B681E
+:101B30003A1B7A3E1B92441B86461B9E501BE0526A
+:101B40001BBF541C015600001C2290FF92E07F0036
+:101B5000FE7C0112324D021C32E4FF04FE7C0312B3
+:101B6000324D742090FFFEF0021C32E4FF04FE7C34
+:101B70000212324D744090FFFEF0021C32E4FF046A
+:101B8000FE7C0412324D021C32E4FF04FE7C05127E
+:101B9000324D021C32E4FF04FE7C0612324D021C60
+:101BA0003290FFA5E07D0090FBF8CDF0A3CDF09042
+:101BB000FBF9E0FCF58390FBF8E04433FD121CC513
+:101BC000807390FFB5E07D0090FBFACDF0A3CDF0DF
+:101BD00090FBFBE0FCF58390FBFAE04443FD121C14
+:101BE000C5805290FFA6E07D0090FBFCCDF0A3CD18
+:101BF000F090FBFDE0FCF58390FBFCE04434FD122B
+:101C00001CC5803190FFB6E07D0090FBFECDF0A3B7
+:101C1000CDF090FBFFE0FCF58390FBFEE04444FD3B
+:101C2000121CC5801090FF92E07D00FCED44AAFDDF
+:101C3000121CC58000E490FF92F0D0E0FFD0E0FEDF
+:101C4000D0E0FDD0E0FCD0E0FBD0E0FAD0E0F9D06D
+:101C5000E0F8D0D0D083D082D0F0D0E0320581053A
+:101C60008105810581A881181818EDF608ECF69019
+:101C7000FF5AE020E70280F790FF59E07D00A8813D
+:101C800018CDF6CD08F67D03A881E618FCE6CC2534
+:101C9000E0CC33CCDDF9CCF6CC08F6A88118E644CC
+:101CA000F8F6A881181818E6FD08E6FCA881188641
+:101CB00083088682EDF0A3ECF0740290FF5AF015D1
+:101CC0008115811581158122E5812405F581E4A81E
+:101CD0008118F6A88118181818EDF608ECF690FB94
+:101CE000F5E024F85003021DE6E4A8811818F6A8D0
+:101CF0008118E6FEA88118181818E6FD08E6FC7F92
+:101D000000EF24F8404DE4EF25E0247DF582E43433
+:101D1000FCF583E0FBA3E06C7003FAEB6D700974D3
+:101D200001A8811818F6802BE4EF25E0247DF582C8
+:101D3000E434FCF5837A00E054F0CCF8CCCDF9CD56
+:101D4000FB7800E954F0F9EA687002EB6970010E63
+:101D50000F80AEA88118EEF6A88118181818EDF6B5
+:101D600008ECF6A881EFF6A8811818E67079A8812A
+:101D700018E624F74071A88118181818E6540FA81F
+:101D800081F664046017A881E664036010A88118D6
+:101D9000181818E6FD08E6FC121C5A804A7C0A1244
+:101DA00031ADA88118181818E6FD08E6FC90FBF480
+:101DB000E025E0247DF582E434FCF583EDF0A3EC2E
+:101DC000F090FBF4E0FFE4EF045407FF90FBF4F025
+:101DD00090FBF5E004F012324690FBF6E07008E468
+:101DE000FEFF7C0F12324D802790FBF7E004F05489
+:101DF0003F701D90FBF7E044FE7D00FC90FBF4E09B
+:101E000025E0247DF582E434FCF583EDF0A3ECF0CD
+:101E1000E58124FBF58122788B7600788C7600743E
+:101E20000190FBF6F012313890FBF5E060577C0A28
+:101E30001231AD90FBF3E025E0247DF582E434FC23
+:101E4000F583E0FDA3E0FC90FBF3E025E0247DF5C5
+:101E500082E434FCF583E4F0A3F090FBF3E0FFE4CC
+:101E6000EF045407FF90FBF3F090FBF5E014F078DB
+:101E700089EDF608ECF61232467889E6FD08E6FCB4
+:101E80001208E380A312329A90FF93E04401F0B26B
+:101E9000B3788B06B60011788B7600788CE6F40464
+:101EA00004A2E092B4788CF6021E25E490FBF6F0D2
+:101EB00090FBF5E07D00FCED44CFFD121C5A123181
+:101EC000BB22123138E5706449456F601590FF837D
+:101ED000E0540F7D00D39570ED956F5005122F8162
+:101EE00080031230511231BB22123138E57064493F
+:101EF000456F600512308B800E90FF80E04408F043
+:101F000090FF83E0547FF01231BB221231388C54A1
+:101F1000EC54F0B41015756A357569FC756801E507
+:101F20006A2403F56AE5693400F569E4F557F55666
+:101F3000E556C394015027E554540FFCAD6AAE69D1
+:101F4000AF68120E808C55EC60028012056AE56A5B
+:101F5000700205690557E5577002055680D2E554B1
+:101F6000540F249DF8E654FEF6E554540F7F00FE0E
+:101F70007C1212324DE5551470097D007C09122542
+:101F8000468007AD577C001225461231BB22123124
+:101F90003890FFFCE04402F090FF00E030E713903F
+:101FA000FF83E04480F0436D8090FFFCE04401F04B
+:101FB000801190FF82E04408F0536D7F90FFFCE0B9
+:101FC00054FEF090FF81E04480F01225F990FFFE6E
+:101FD000E04405F090FFFCE054FDF01231BB22120A
+:101FE00031387C011232FB78ADE64402F674FEFC17
+:101FF00004FD121CC590FF5AE030E70280F7E4F5BB
+:102000004E754D10AC4EAD4DE54E154E7002154D52
+:10201000EC4D600280EE4387011231BB2212313851
+:102020007C021231C778ADE654FDF61231BB2212A4
+:10203000313878ADE630E02C78ADE630E12678AD89
+:10204000E6FCF58318E644F0FD121C5A90FFFCE014
+:102050004420F07C021232FB78ADE654FDF6741A8F
+:1020600090FFFEF078ADE6FCF58318E644F1FD1232
+:102070001C5A1231BB22756D0090FFFFE0600343D4
+:102080006D01756E00E4F56CF56BE4F56F757049E4
+:10209000748490FF82F0748490FF80F0748090FFCD
+:1020A00058F0748090FF5AF0AD46AF457E00EE24A4
+:1020B000FE5003022142E4EE75F007A4247FF5826E
+:1020C000E434F8F583E0FFE4EF5480FDE4EF540FCF
+:1020D00014FFED6038E4EF75F008A42448F582E4BD
+:1020E00034FFF5837490F0E4EF75F008A4244AF50A
+:1020F00082E434FFF5837480F0E4EF75F008A424E3
+:102100004EF582E434FFF5837480F08034E4EF759B
+:10211000F008A42408F582E434FFF5837490F0E419
+:10212000EF75F008A4240AF582E434FFF583E4F0A7
+:10213000E4EF75F008A4240EF582E434FFF583E49F
+:10214000F00E0220AB8D468E448F45747F90FFFDCC
+:10215000F0749090FFFCF0228C58EC24F65006E5C9
+:10216000582437FC22E5582430FC22D2B0122543F3
+:10217000EC700302227E755C03AE5B7F00E55C15AC
+:102180005C6480247F5035EF2400F582E434FBF555
+:1021900083E0FE24FE501EEF7D00FCE4FB7474C35C
+:1021A0009CFAEB9DFBEE7D00FCEAC39CED6480CBCA
+:1021B00064809B50028005EF2EFF80C18E5B8F5A9A
+:1021C000E55C6480247F500302227EE55A248E5011
+:1021D0000302227E855A5D755B00AE5AAF5B903577
+:1021E000EEE493F55CE55C155C6480247F5018EEAA
+:1021F0002400F582E434FBF583E0FCEF9035EE93A8
+:102200006C70040E0F80DE8E5A8F5BE55C64802458
+:102210007F406E755E017560E8755FFFE55D2402C5
+:10222000F55A755C07E55C334057AD60AE5FAF5E55
+:10223000E55CF5823395E0F5831201F5C4540FFC9B
+:10224000122155E55A2400F582E434FBF583ECF0C5
+:10225000055A055AAD60AE5FAF5EE55CF582339519
+:10226000E0F5831201F5540FFC122155E55A2400C4
+:10227000F582E434FBF583ECF0055A055A155C80D1
+:10228000A4740290F851F090F86B79C77A357B27E7
+:1022900078011203FE756A357569FC756801E49072
+:1022A000FF83F0748090FF81F0755902E55975F055
+:1022B00007A4247FF582E434F8F583E0788FF6FCF8
+:1022C000540F14FC788FECF6E55975F007A42481BF
+:1022D000F582E434F8F583E0789276FD0876E8FC40
+:1022E000788FE675F008A42448F582E434FFF5837E
+:1022F000E4F0788FE675F008A4244FF582E434FF0B
+:10230000F583ECF07892E6FF08E67E03CFC313CFA7
+:1023100013DEF9FE788FE675F008A42449F582E40F
+:1023200034FFF583EEF0788FE675F008A4244AF5C3
+:1023300082E434FFF5837480F07890ECF67D0078C9
+:1023400093E62CF618E63DF67892E6FD08E67C0367
+:10235000CDC313CD13DCF9FC788FE675F008A42407
+:102360004DF582E434FFF583ECF0788FE675F008E4
+:10237000A4244EF582E434FFF583E4F07892E6FD80
+:1023800008E6FC788FE6FF7E00EE24FE5003022470
+:10239000FDE4EE75F007A4247FF582E434F8F583BC
+:1023A000E0FFE4EF5480FAE4EF540F14FFE4EE751D
+:1023B000F007A42481F582E434F8F583E07890F600
+:1023C000E4EE1313548024F0F8E434FDF9E8FCE95A
+:1023D000FD8A5AEA700302246AE4EF75F008A42427
+:1023E00048F582E434FFF583E4F07890E6FAE4EF10
+:1023F00075F008A4244FF582E434FFF583EAF0ED8C
+:10240000FBEC7A03CBC313CB13DAF9FAE4EF75F0E4
+:1024100008A42449F582E434FFF583EAF07890E6D5
+:102420007B00FAEC2AFCED3BFDFBEC7A03CBC313FB
+:10243000CB13DAF9FAE4EF75F008A4244DF582E441
+:1024400034FFF583EAF0E4EF75F008A4244AF5823E
+:10245000E434FFF5837480F0E4EF75F008A4244EB3
+:10246000F582E434FFF5837480F00224F9E4EF751B
+:10247000F008A42408F582E434FFF583E4F07890B2
+:10248000E6FAE4EF75F008A4240FF582E434FFF5D2
+:1024900083EAF0EDFBEC7A03CBC313CB13DAF9FA42
+:1024A000E4EF75F008A42409F582E434FFF583EA2B
+:1024B000F07890E67B00FAEC2AFCED3BFDFBEC7A31
+:1024C00003CBC313CB13DAF9FAE4EF75F008A424B5
+:1024D0000DF582E434FFF583EAF0E4EF75F008A42B
+:1024E000240AF582E434FFF583E4F0E4EF75F008A4
+:1024F000A4240EF582E434FFF583E4F00E02238673
+:102500008E597892EDF608ECF6788FEFF61220737C
+:10251000228C26EC30E718E526540F1475F008A439
+:102520002448F582E434FFF583E054DFF08016E5BB
+:1025300026540F1475F008A42408F582E434FFF53E
+:1025400083E054DFF0227C0022EC90FC37F08C24F6
+:10255000ED2403F5257D00D39572ED95714003853B
+:102560007225E52524B75009752503740290FC37C0
+:10257000F0AC2512307622E4F56CF56B12257D2245
+:1025800090FC35E06573600E740490FC37F0E4F560
+:102590006B756C0380467D73E4FEFF79357AFC7BB6
+:1025A0000174057800120348E56C2403F56CE56BB3
+:1025B0003400F56BE56CD39572E56B95714006853B
+:1025C000726C85716BD3E56C9448E56B9400400C9C
+:1025D000740290FC37F0E4F56B756C03AC6C123050
+:1025E0007622EC90FC37F0E4F56CF56B8C32EC6005
+:1025F0000512306780057C001230762290FF93E050
+:102600004401F0B2B390FF04E0F54A90FF06E0FD0C
+:10261000A3E0ED7D00FC7D00FC90FF06E0FFA3E061
+:102620007E00FFE4FEEC4EFCED4FFDC3EC9448ED64
+:102630009400502290FF06E0FDA3E0ED7D00FC7DBC
+:1026400000FC90FF06E0FFA3E07E00FFE4FEEC4EFE
+:10265000FCED4FFD8004E4FD7C488C728D7190FF91
+:1026600002E0FDA3E0ED7D00FC7D00FC90FF02E0B8
+:10267000FFA3E07E00FFE4FEEC4EF54CED4FF54B82
+:10268000756A357569FC7568017D357EFC7F017959
+:1026900073E4FAFB74057800120348754900E549B4
+:1026A00024FE4019AD6AAE69AF68E412031805490B
+:1026B0000DED70010E8D6A8E698F6880E1756A3547
+:1026C0007569FC75680190FF00E05460B4000280F9
+:1026D00006D35003022CBFE54A540FF549E54A548E
+:1026E00080A2E0920290FF01E012018A000B2CBA56
+:1026F000270528232CBA292F2CBA2A122A462BADBB
+:102700002BB02BF02C632C91E56D30E70EE54C459A
+:102710004B7008E572640245716003022CBC90FFA7
+:1027200000E0541FB400028003D34029E54A60034F
+:10273000022820AD6AAE69AF68740112031878AD43
+:10274000E630E00BAD6AAE69AF6874021203187C24
+:102750000212307622B401028003D3401BE56D20C3
+:10276000E107E54A6003022820E54A24FE500302FF
+:1027700028207C0212307622B402028006D3500355
+:1027800002281EE56D20E10DE54A6009E54A6480F6
+:102790006003022820AC4A1230FD4003022820E5E5
+:1027A00049702530021190FF80E05408AD6AAE698F
+:1027B000AF68120318800F90FF82E05408AD6AAE34
+:1027C00069AF68120318803D154930021DE549754F
+:1027D000F008A42448F582E434FFF583E05408AD02
+:1027E0006AAE69AF68120318801BE54975F008A44A
+:1027F0002408F582E434FFF583E05408AD6AAE693D
+:10280000AF68120318AD6AAE69AF681201EF600BD2
+:10281000AD6AAE69AF6874011203187C021230769B
+:10282000228000022CBCE56D20E706E57245716050
+:1028300003022CBC90FF00E0541FB400028003D3BD
+:10284000401AE54C14454B7004E54A600302292CFC
+:1028500078ADE654FEF67C0012307622B401028098
+:1028600003D3402AE56D20E108E56D20E00302294D
+:102870002CE56D30E004E54A700BE56D30E109E5CB
+:102880004A24FE500302292C7C0012307622B40226
+:10289000028006D3500302292AE54C454B6003020F
+:1028A000292CAC4A1230FD400302292CE56D20E1B1
+:1028B00007E56D20E0028077E56D30E006E54960D0
+:1028C00002806CE549700F90FF82E054F7F090FFB2
+:1028D00080E054F7F022E549B401028003D34009B7
+:1028E0007D017C03120F128011B402028003D340D9
+:1028F000097D017C04120F1280001549300215E594
+:102900004975F008A42448F582E434FFF583E054C7
+:10291000F7F08013E54975F008A42408F582E43443
+:10292000FFF583E054F7F07C00123076228000023D
+:102930002CBCE56D20E706E57245716003022CBCF6
+:1029400090FF00E0541FB400028003D3401AE54C0E
+:1029500014454B7004E54A6003022A0F78ADE64443
+:1029600001F67C0012307622B401028003D34029A4
+:10297000E56D20E108E56D20E003022A0FE56D30EA
+:10298000E004E549700BE56D30E108E54924FE50AF
+:1029900002807F7C0012307622B402028003D34092
+:1029A0006FE54C454B60028069AC4A1230FD400235
+:1029B0008060E56D20E107E56D20E0028054E54987
+:1029C000701430020990FF80E04408F0800790FF07
+:1029D00082E04408F022E56D30E1331549300215FC
+:1029E000E54975F008A42448F582E434FFF583E056
+:1029F0004408F08013E54975F008A42408F582E442
+:102A000034FFF583E04408F07C0012307622800227
+:102A10008000022CBCE56D20E712E5724571700C58
+:102A2000E54A700890FF00E0541F6003022CBCE5EB
+:102A30004C90FFFFF090FFFFE06005436D018003C5
+:102A4000536DFE7C0012307622E56D30E70EE572A4
+:102A50004571600890FF00E0541F6003022CBCAD7C
+:102A60004BE54CED7D00FC7D00FCBD0002800302C7
+:102A70002BA8B401028003D34032E54A7005E54C2F
+:102A8000FC6003022BAA756A407569F8756801D36A
+:102A9000E5729412E57194004006E4FD7C12800416
+:102AA000AC72AD718C708D6F12308B22B4020280CB
+:102AB00003D34059E54A6003022BAAE54CFC70277A
+:102AC000756A527569F8756801D3E5729419E571F4
+:102AD00094004006E4FD7C198004AC72AD718C70EA
+:102AE0008D6F12308B8025756A6B7569F87568017A
+:102AF000D3E5729427E57194004006E4FD7C2780BD
+:102B000004AC72AD718C708D6F12308B22B40302E5
+:102B10008006D35003022BA8E54CF549700F90FFB7
+:102B200004E0FDA3E04D6003022BAA801890FB0295
+:102B3000E0FDA3E0FC90FF05E06C700790FF04E06F
+:102B40006D60028068E4F570F56F7F00E54914C59B
+:102B500049600FEF2400F582E434FBF583E02FFF9A
+:102B600080EA8F4AE54A2400F582E434FBF583E0ED
+:102B70007D00D39572ED95714006AC72AD71800FFA
+:102B8000E54A2400F582E434FBF583E07D00FC8C0B
+:102B9000708D6FE54A2400FCE434FBFDFEECFD7F04
+:102BA000018D6A8E698F6812308B228000022CBCE6
+:102BB000022CBCE56D30E719E5721445717012E521
+:102BC0004A700EE54C454B700890FF00E0541F60C2
+:102BD00003022CBCE56D20E008E56D20E103022C2A
+:102BE000BC756A6EE4F569F568E4F56F04F570127A
+:102BF000308B22E56D20E727E57245717021E54AAB
+:102C0000701DE54C6402454B600DE54C14454B606E
+:102C100006E54C454B700890FF00E0541F6003022E
+:102C20002CBCE56D20E008E56D20E103022CBC859D
+:102C30004C6EE56E700A436D01536DFDD2B080207D
+:102C4000E56E64026007E56E1460028072536DFEEB
+:102C5000436D02E56E64026005E56E147002C2B059
+:102C60007C0012307622E56D30E71AE5721445716A
+:102C70007013E54A700FE54C454B700990FF00E07A
+:102C8000541F1460028038E56D20E10280317C0120
+:102C900012307622E56D20E715E5724571700FE57B
+:102CA0004C454B700990FF00E0541F146002800FE8
+:102CB000E56D20E10280087C00123076228000025F
+:102CC0002F7DB440028006D35003022F7390FF0182
+:102CD000E090FC35F0E54A90FC36F0E490FC37F0EB
+:102CE000E56A2403F56AE5693400F569AD4BE54C06
+:102CF000856A82856983CDF0A3CDF090FF01E01253
+:102D000001C02D2A012D50022D7A032DA4042DF28D
+:102D1000052E2F062E55072E7B082EA7092ECD0B2C
+:102D20002EF30C2F02802F028100002F60E56D2012
+:102D3000E7067C051225DF227D767E357F02793815
+:102D40007AFC7B01740878001203487D087C00122D
+:102D5000254622E56D20E7067C051225DF22E54A9F
+:102D6000B403004010B40500500BE54A7F00FE7C20
+:102D70001012324D227D007C0712254622E56D207F
+:102D8000E7067C051225DF22E54AB403004010B4B3
+:102D90000500500BE54A7F00FE7C1112324D227D6A
+:102DA000007C0712254622E56D20E7067C051225EA
+:102DB000DF22E54AB405028003D3400AE4FF04FEA3
+:102DC0007C0A12324D22B401028003D3400AE4FF90
+:102DD00004FE7C0812324D22B403004010B40500FA
+:102DE000500BE54A7F00FE7C1312324D227D007CA1
+:102DF0000712254622E56D20E734D3E5729448E5B5
+:102E00007194005006E572457170067C021225DF50
+:102E100022E54AB40103B3400BC3B403004009B434
+:102E200006005004123123227C071225DF221225CE
+:102E30007D22E56D20E71DE54AB403004010B4058E
+:102E400000500BE54A7F00FE7C1612324D227C07B3
+:102E50001225DF2212257D22E56D20E71DE54AB40B
+:102E600003004010B40500500BE54A7F00FE7C19BA
+:102E700012324D227C071225DF2212257D22E56DBC
+:102E800020E723748190FF93F0E54AB403004010DB
+:102E9000B40500500BE54A7F00FE7C1712324D222C
+:102EA0007C071225DF2212257D22E56D20E71DE536
+:102EB0004AB403004010B40500500BE54A7F00FE01
+:102EC0007C1812324D227C071225DF2212257D222A
+:102ED000E56D20E71DE54AB403004010B40500503D
+:102EE0000BE54A7F00FE7C1512324D227C0712252D
+:102EF000DF2212257D22E56D20E7067C071225DF03
+:102F00002212257D22E56D30E72090FF00E0541F5E
+:102F1000701090FF01E0B480051225748003122523
+:102F20007D227D007C051225462290FF00E0541F83
+:102F300060067C051225DF22D3E5729448E5719482
+:102F400000500BC3E5729407E571940050067C03B2
+:102F50001225DF22E54AB40504123123227C071230
+:102F600025DF22E56D30E7087D007C05122546222D
+:102F70007C051225DF22B420028003D340008000AC
+:102F80001230512275430090FF83E0540FD39543D4
+:102F90004024E54324F0F582E434FEF583E0AD6A95
+:102FA000AE69AF6812031805430DED70010E8D6A0E
+:102FB0008E698F6880D1E5437D00FCC3E5709CF588
+:102FC00070E56F9DF56FE570456F6006E490FF83D7
+:102FD000F02290FF82E04408F0E4F56F75704990AC
+:102FE000FC35E0B405028003D3404090FC36E0F5A8
+:102FF00043B405028003D3400AE4FF04FE7C0B12B5
+:10300000324D22B401028003D3400AE4FF04FE7C67
+:103010000912324D22B403004010B40500500BE5F4
+:10302000437F00FE7C1412324D2222B480004023E4
+:10303000B48200501E7C357DFC1217A57D008C6C7F
+:103040008D6B90FC37E0600512305180057C0012DA
+:103050003076222290FF83E0547FF090FF82E0449C
+:1030600008F090FF80E04408F02290FF82E04408DE
+:10307000F090FF80E04408F0228C237D008C708D5E
+:103080006F756A357569FC75680112308B2290FF87
+:1030900083E0547FF0E5706449456F700122C3E519
+:1030A000709408E56F94004015752108E5217D00B6
+:1030B000FCC3E5709CF570E56F9DF56F8009857028
+:1030C00021E4F56F757049752200E522C395215002
+:1030D00026AD6AAE69AF681201EFFCE52224F8F56F
+:1030E00082E434FEF583ECF005220DED70010E8DC7
+:1030F0006A8E698F6880D3E521547F90FF81F0222A
+:103100008C487F00EF24FD4019E4EF75F007A424FC
+:103110007FF582E434F8F583E065487002D3220F2E
+:1031200080E28F47C32285727085716F90FF82E0C5
+:1031300054F7F090FF83E0547FF022C000C001C03C
+:1031400002C006C007E5782408F8860653067F7C8F
+:10315000FF1231AD7C007D00E57B6046FF90FD9560
+:10316000E0547F6E700FC083C082A3E0FDA3E0FC3B
+:10317000A3157B8007A3A3A3DFE68026DF06D0820A
+:10318000D083801EE0F8A3E0F9A3E0FAD082D083D8
+:10319000E8F0A3E9F0A3EAF0A3C083C082A3A3A34D
+:1031A00080DA123246D007D006D002D001D00022F9
+:1031B00085A87A75A888EC70027C3F8C7922E57826
+:1031C0002408F8760012329A80FBC000C001C002C9
+:1031D000C006C007AE047CFF1231ADE57B6042FF44
+:1031E00090FD95E0547F6E700BC083C082A3A3A3B3
+:1031F000157B8007A3A3A3DFEA8026DF06D082D059
+:103200008380D8E0F8A3E0F9A3E0FAD082D083E885
+:10321000F0A3E9F0A3EAF0A3C083C082A3A3A38034
+:10322000DA7808087918097C01E6547F6E70067612
+:10323000007700800608090CBC08EE123246D00761
+:10324000D006D002D001D00022757900857AA8225C
+:10325000C0F0C082C083C3E57B24E8500512329AD7
+:1032600080F4EC6031903575E493C39C4028C00431
+:103270007CFF1231ADD004430480E57B75F003A4DC
+:103280002495F582E434FDF583ECF0EFA3F0EEA392
+:10329000F0057B123246D083D082D0F022C0047C6D
+:1032A00020D28CD28DD504FDD0042275A80075885B
+:1032B0000075B80075F00075D000E4F8900000F6D5
+:1032C00008B800FB020000C3ED940250047D037CAB
+:1032D000E8ECF4FCEDF4FD0CBC00010D8C7F8D7E60
+:1032E00022C3EC94BCED940250047D077CD0ECF436
+:1032F000FCEDF4FD0CBC00010D8C7D8D7C22EC708E
+:103300000122C000E5782418F8A604E5782408F81E
+:10331000C6547FF6E630E703D0002212329A80F4DA
+:10332000C28C857C8C857D8AD28CC0E0C0D0C0F0F8
+:10333000C082C083C000C001C002C003C004C00579
+:10334000C006C007121AF8E5782408F8E66024E5FC
+:10335000782410F8A681E57875F021A4248DF582F3
+:10336000E434FCF58378AEE58104C398F9E6F0080F
+:10337000A3D9FA74082578F8057808E65480700C0B
+:10338000E578B407F3780875780080EFE5782410C5
+:10339000F88681E57875F021A4248DF582E434FC6B
+:1033A000F58378AEE58104C398F9E0F608A3D9FA6D
+:1033B000D007D006D005D004D003D002D001D00071
+:1033C000D083D082D0F0D0D0D0E032C0E0C0D0C026
+:1033D00000C001C002C28E857E8D857F8BD28E7823
+:1033E0001979097A07E77004A600800BE6600816D1
+:1033F000E67004E74480F70809DAEAE57960131417
+:10340000F579700EE5782408F87600123246D28CF1
+:10341000D28DD002D001D000D0D0D0E0327581ADB5
+:10342000742A90FF93F0757F30757EF8757D607516
+:103430007CF012053F1234CE12175B90FF93E044EC
+:1034400001F0B2B31234F81232A880DA22C0007C44
+:1034500001EC2408F8E660090CBC08F512329A80E9
+:10346000EED00022C0F0C082C083C000C006C007FA
+:10347000ED2410F876BCED75F021A4248DF582E4DE
+:1034800034FCF583C082C083A3A3E4780DF0A3D8F5
+:10349000FCEC547F75F002A42441F582E5F034354C
+:1034A000F583E493FE740193F5828E83E493FE74B6
+:1034B0000193FFD083D082EFF0A3EEF0ED2408F863
+:1034C000EC4480F6D007D006D000D083D082D0F074
+:1034D00022757800757B007A08791878087600776D
+:1034E000000809DAF8E478087480447FF67401442F
+:1034F00010F58975B808D2ABD2A9227581ADD28EEC
+:10350000D28CD2AFE57B6032FF90FD95E0548060B5
+:103510002478087908E0547FFA7B00E6547FB502EE
+:10352000027BFF08D9F5EB700CEAF012344AAD04C7
+:10353000AC02123461A3A3A3DFD212329A80C57CFD
+:10354000017D002204FE04F204F604EA04E604E22B
+:1035500004EE04FA04A604AA04D604DA04A204A21F
+:1035600004A204DE04BE04B604BA04B204CA04C64B
+:1035700004C204CE04D204AE1901030022004802A2
+:1035800000480E301420C81AD0180A0C0506020391
+:1035900001020001CE0181010000C0008000600036
+:1035A0003000180010000800040002000100081894
+:1035B00028380C05100A0200000000000301100A60
+:1035C000020000000000FBE0FBF2090227000102FC
+:1035D00000A0FA0904000003FF00000007058102B3
+:1035E00040000007050102400000070583030200B8
+:1035F00001220354005500530042003300340031CF
+:1036000000300020002000200020002000200020AA
+:073610000020000000000093
+:00000001FF
diff --git a/firmware/mts_edge.fw.ihex b/firmware/mts_edge.fw.ihex
new file mode 100644
index 0000000..d14ebd6
--- /dev/null
+++ b/firmware/mts_edge.fw.ihex
@@ -0,0 +1,881 @@
+:10000000F0360002001E021AFBFFFFFFFFFF023363
+:10001000F9FFFFFFFFFFFFFFFFFFFFFFFFFF0234BE
+:10002000A47581D490FDE88583A0123618EC4D604C
+:100030007378AF8003760018B8A0FA787F800376D3
+:100040000018B865FA78208003760018B820FA788E
+:10005000208003760018B81FFA90FDDDAE83AF82D2
+:1000600090FBF81200AA6005E4F0A380F690FDE88A
+:10007000A88290FDE8A982E8696005E4F20880F7AB
+:100080009001081200B390010C1200B390011012FD
+:1000900000B39001141200D190011A1200D1900106
+:1000A000201200D175D0001234F6020126EF6582CD
+:1000B0007003EE658322E493F8740193F97402935C
+:1000C000FE740393F5828E83E869700122E493F64F
+:1000D000A30880F4E493FC740193FD740293FE740E
+:1000E0000393FF740493F8740593F58288831200D8
+:1000F000AA700122E493A3A883A9828C838D82F045
+:10010000A3AC83AD828883898280E32121049B8014
+:1001100080049BB0B4049BFDE8049F049FFBF304A0
+:10012000A4049FFBF30504050480FED0F030F00921
+:1001300020F303F68010F7800D30F10920F303F26D
+:100140008004F38001F020F404FCD0E0CC22CCC089
+:10015000E0120163020154BC0005D0F0ACF022C3F0
+:1001600013DCFC02012ABF0009ED258275F001F8BD
+:10017000E622BF010FED2582F582EE3583F583750A
+:10018000F004E022ED258275F002F8E222D083D05F
+:1001900082F5F0C3E493A3C5F095F0C0E0C3D0F0BE
+:1001A000E493A395F04012A3A3C3E5F033500205F6
+:1001B000832582F58250020583740193C0E0E493A5
+:1001C000C0E022D083D082F5F0E4937009740193EB
+:1001D0007004A3A3800C74029365F06005A3A3A32D
+:1001E00080E7740193C0E0E493C0E022120264024D
+:1001F00001FB1202B80201FB1202DC0201FB30E03B
+:100200000720E302E622E72230E10720E302E222B0
+:10021000E32230E202E022E493221202DC02022313
+:100220001202B8020223ABF012022DCBC5F0CB2292
+:1002300030E01020E306E6F5F008E622E7F5F009E5
+:10024000E7192230E11020E306E2F5F008E222E3AC
+:10025000F5F009E3192230E206E0F5F0A3E022E42C
+:1002600093F5F074019322BB0003740922BB0107CC
+:1002700089828A83740422BB020789828A8374106C
+:1002800022740A22020284BB0007E92582F8740165
+:1002900022BB010DE92582F582EA3583F5837404DA
+:1002A00022BB020DE92582F582EA3583F5837410BD
+:1002B00022E92582F87402220202B8BF0005EDF897
+:1002C000740122BF01078D828E83740422BF02074E
+:1002D0008D828E83741022EDF87402220202DCBF3C
+:1002E0000007ED2582F8740122BF010DED2582F58E
+:1002F00082EE3583F583740422BF020DED2582F56D
+:1003000082EE3583F583741022ED2582F874022283
+:10031000020310C0E0120264020328C0E01202B817
+:10032000020328C0E01202DC02032830E00B20E3C5
+:1003300004D0E0F622D0E0F72230E10B20E304D035
+:10034000E0F222D0E0F322D0E0F022C9CDC9CACE3B
+:10035000CACBCFCB12035BEDF9EEFAEFFB22BB0069
+:100360002FBF000AFAEDF8E7F60809DAFA22BF0112
+:10037000128D828E83F802037809A3E7F0D8FA225F
+:10038000020383FAEDF8E7F20809DAFA2202038D94
+:10039000BB014DBF001489828A83F9EDF802039FE7
+:1003A00008A3E0F6D9FA220203B0BF01228D828EA3
+:1003B00083FB08C9C582C9CAC583CAE0A3C9C5826F
+:1003C000C9CAC583CAF0A3DBEAD8E8220203D38DE9
+:1003D000828E83F9EDF8E0F208A3D9FA220203DD58
+:1003E000BB024DBF001289828A83F9EDF80203EF48
+:1003F00008A3E493F6D9F922BF01238D828E83FBF3
+:1004000008C9C582C9CAC583CAE493A3C9C582C93C
+:10041000CAC583CAF0A3DBE9D8E722020422898295
+:100420008A83F9EDF8E493F208A3D9F922020433A0
+:10043000BF000DFAEDF8E3F60809DAFA2202043DEE
+:10044000BF01128D828E83F802044A09A3E3F0D81B
+:10045000FA22020455FAEDF8E3F20809DAFA220268
+:10046000045FE6FB08E6FA08E6F904F618700106F0
+:1004700022E6FF08E6FE08E6FD22EFF0A3EEF0A379
+:10048000EDF022EBF0A3EAF0A3E9F022E0FFA3E015
+:10049000FEA3E0FD22E0FBA3E0FAA3E0F9220000C6
+:1004A000000000000000000504006105730026053F
+:1004B0009A00330A0B00610A770066154600610C4A
+:1004C000FB006109AB006109E200610DC200610B34
+:1004D000F300610A1E00610A530061173E003317E2
+:1004E0005100341E1600431EBC0044202900442045
+:1004F0001700471EE300471F88004D1FD9004F1FFC
+:10050000050058338400617CCC7DFF121CC722900B
+:10051000FFFCE020E72DC2AFAE59AF58755A20E579
+:100520005A14C55A6019E4FE7F05EE4FCE24FFCE63
+:10053000CF34FFCF6007E490FF92F080ED80E08E33
+:10054000598F582212050C7D077CB71233A07D0FFE
+:100550007C6E1233BA78A17A06E4F608DAFC7A06E1
+:100560001205CF7C03120E57122165E4FEFF7C0FAB
+:10057000123329D2A822123214E490FC38F090FFF2
+:10058000F0E030E408740190FC39F08005E490FC60
+:1005900039F07D0A7C00122547123297221232145C
+:1005A00090FC39E014700E90FFF0E04410F07C00F5
+:1005B0001225E0801990FC39E0700E90FFF0E054B5
+:1005C000EFF07C001225E080057C171225E0123246
+:1005D000972290FFF0E054ABF090FFF0E04420F061
+:1005E000228C378D367882EDF608ECF6EDFEECFDC8
+:1005F0007F019000051201F57880F67882E6FD080B
+:10060000E6FCEDFEECFD7F019000041201F5540FB5
+:10061000FC7D8012176F7880E6700DAD3AAE39AF71
+:1006200038E41203187C082290FFF0E054FEF090AA
+:10063000FFF0E054FDF0801E7882E6FD08E6FCED58
+:10064000FEECFD7F0190000812021725E0440190A6
+:10065000FFF3F00206DB7882E6FD08E6FCEDFEEC37
+:10066000FD7F0190000612021754FE90FFF3F08008
+:100670002B7882E6FD08E6FCEDFEECFD7F019000A4
+:1006800008120217FAEB90FFF1F01208CA400DAD04
+:100690003AAE39AF38E41203187C18227882E6FDAE
+:1006A00008E6FCEDFEECFD7F0190000812021790B9
+:1006B000FFF1F01208CA400DAD3AAE39AF38E4127E
+:1006C00003187C18227882E6FD08E6FCEDFEECFDBE
+:1006D0007F01900006120217440190FFF3F0788327
+:1006E000E62403F618E63400F67880E624FE500986
+:1006F00090FFF0E054FDF0800790FFF0E04402F03E
+:10070000E490FFF1F0788176007880E624FFFCE445
+:1007100034FFFD7881E67F00FEECD39EEF6480CD50
+:1007200064809D402F1208AF400F7881E6AD3AAE4D
+:1007300039AF381203187C182290FFF2E0FC78825F
+:100740008683088682ECF0788106A37882A68308E7
+:10075000A68280B51208AF400F7881E6AD3AAE3977
+:10076000AF381203187C182290FFF2E0FC788286E2
+:1007700083088682ECF07880E6AD3AAE39AF381265
+:1007800003187C00228C378D367882EDF608ECF663
+:10079000EDFEECFD7F019000051201F57881F67801
+:1007A00082E6FD08E6FCEDFEECFD7F019000041200
+:1007B00001F5540FFC7D8112176F7881E670037C80
+:1007C000082290FFF0E054FEF090FFF0E054FDF0BE
+:1007D000801B7882E6FD08E6FCEDFEECFD7F0190D3
+:1007E000000812021725E090FFF3F0805B7882E6A4
+:1007F000FD08E6FCEDFEECFD7F01900006120217FD
+:1008000054FE90FFF3F080217882E6FD08E6FCEDCF
+:10081000FEECFD7F01900008120217FAEB90FFF149
+:10082000F01208CA40037C18227882E6FD08E6FC34
+:10083000EDFEECFD7F0190000812021790FFF1F031
+:100840001208CA40037C18227883E6240AF618E6C8
+:100850003400F6788076007881E624FFFCE434FFEB
+:10086000FD7880E67F00FEECD39EEF6480CD64804F
+:100870009D402178828683088682E090FFF1F01205
+:1008800008CA40037C1822788006788306E6187030
+:10089000010680C390FFF0E04401F078828683086F
+:1008A0008682E090FFF1F01208CA40037C18227C97
+:1008B000002290FFF0E020E71290FFF0E030E50921
+:1008C00090FFF0E04420F0C32280E7D32290FFF0B5
+:1008D000E020E31290FFF0E030E50990FFF0E04403
+:1008E00020F0C32280E7D3228C428D417C00ED545E
+:1008F000F0FDEC7003ED64307005753E0380037508
+:100900003E04AC3E120F74758300858340E541546C
+:100910000FF53FE5407004E53F64037035E53E2484
+:10092000FD75F00AA42402F582E434FCF583E0307E
+:10093000E60512105B8019E53E24A1F8E654FBF6AB
+:1009400078ADE62405F58218E63400F583740FF0DF
+:100950008059E5407004E53F64047048E53E24FD9D
+:1009600075F00AA42402F582E434FCF583E030E556
+:1009700007AC42AD41121C5CE54230E21578B1E6AD
+:1009800030E00F78B1E630E109E4FF04FE7C0412A8
+:10099000332978ADE62406F58218E63400F5837431
+:1009A0000FF08007E4FC7DEE121C5CC203221232C1
+:1009B00014120F7478ADE62406F58218E63400F5BB
+:1009C00083E090FC38F078ADE62405F58218E63433
+:1009D00000F583E090FC39F0C2037D027C00122513
+:1009E00047123297221232147899ECF6EC24A1F8CF
+:1009F000E630E1077C131225E0800F90FC39E0FD22
+:100A00007899E6FC1213F11225E012329722123285
+:100A1000147899ECF67D00120F141225E01232972B
+:100A2000221232147899ECF6EC24A1F8E630E207B1
+:100A30007C131225E0801B7899E624A1F8E620E1DA
+:100A4000077C121225E0800A7899E6FC1214151230
+:100A500025E0123297221232147899ECF6EC24A198
+:100A6000F8E620E2077C111225E0800A7899E6FC7E
+:100A70001215161225E0123297221232147899ECD0
+:100A8000F6120F7478ADE62409F58218E63400F505
+:100A900083E090FC3FF078ADE6240AF58218E63456
+:100AA00000F583E090FC40F078ADE62403F5821871
+:100AB000E63400F583E0FC78ADE62404F58218E620
+:100AC0003400F583E0F56278ADE62402F58218E69D
+:100AD0003400F583E0F5638C61E4EC333354017842
+:100AE00099F66008E56230E1037899067899E69016
+:100AF000FC41F078ABE62402F58218E63400F58379
+:100B0000E0FDA3E0540CFCED54E68C65F564E56172
+:100B100030E503436501E56220E50EE561547F7031
+:100B200008E56120E703436502E56130E3034365BF
+:100B300010E56130E203436520E56154036003433F
+:100B40006540E56130E103436580E56130E40343DE
+:100B50006401E56130E603436408E56220E40EE5E4
+:100B600061547F7008E56120E7034364105365FB1F
+:100B70005364F9AD64E56590FC3ACDF0A3CDF0E5A2
+:100B80006330E30DE5635430C4540F90FC3DF080B6
+:100B900005E490FC3DF0E563540390FC3CF0E56314
+:100BA0005404C31390FC3EF090FC3CE0700E7D3585
+:100BB0007EFC7F01740190000912014B78ADE624A0
+:100BC00008F58218E63400F583E07C00FD78ADE698
+:100BD0002407F58218E63400F583E07F004CFEEF31
+:100BE0004D90FC38F0A3CEF0CEC2037D0A7C0012FB
+:100BF0002547123297221232147899ECF6789E76B5
+:100C0000010876FC087638789B760C789E12046E84
+:100C100012021D789CCBF6CB08F67F00EF24EA4049
+:100C20001FE4EF25E090365AFD93CD0493789D663E
+:100C30007003ED18667006789B760080030F80DCE9
+:100C4000789AEFF6789E12046E90000212021778DE
+:100C50009CCBF6CB08F65404CB54064B6004789B2F
+:100C6000760B789DE630E313789E12046E900005B3
+:100C70001201F524FB5004789B760D789DE654C054
+:100C80007D0064C04D7004789B760B789E12046ED4
+:100C90009000041201F524FC5004789B760F789E96
+:100CA00012046E9000061201F524FD5004789B7624
+:100CB0000E789E12046E9000091201F524FD500476
+:100CC000789B760A789BE6702A7899E6FC120F7476
+:100CD000789E12046E78ABE6F978AAE6FA7B017486
+:100CE0000A7800120348C2037899E6FC12111778BB
+:100CF0009BECF6789BE6FC1225E01232972212322A
+:100D0000147899ECF6120F747899E624FD75F00AC0
+:100D1000A42414F582E434FCF583AC82AD8378AA74
+:100D20008683088682ECF9EDFA7B0A78011203B01B
+:100D3000C2037899E6FC121117123297228D2B8C80
+:100D40002AED60407527017529487528FFE52A249A
+:100D5000FDFCE434FFFDEC7C0325E0CD33CDDCF974
+:100D6000FCE5292CF529E5283DF528AD29AE28AF6D
+:100D700027748090000612032074809000021203F2
+:100D800020120FC7E52B14603B75270175290875E4
+:100D900028FFE52A24FDFCE434FFFDEC7C0325E07C
+:100DA000CD33CDDCF9FCE5292CF529E5283DF528E6
+:100DB000AD29AE28AF27E4900006120320E490008E
+:100DC00002120320221232147899ECF6EC24A1F8D6
+:100DD000E630E2097899E6FC121516D2007899E619
+:100DE000FC120F74789A760090FC39E030E70478B2
+:100DF0009A7601789AE6FD7899E6FC120D3AC203DC
+:100E00003000077899E6FC1214157C001225E012D8
+:100E100032972278ADE62404F58218E63400F58393
+:100E2000E04401F078ADE62404F58218E63400F5DC
+:100E300083E030E00280ED78ADE6240BF58218E621
+:100E40003400F583E054F8F078ADE62402F582181A
+:100E5000E63400F583E04480F022C2038C58120F80
+:100E60007478AA8683088682798B7A367B0A780121
+:100E70001203FE120E10AC587D02120D3AC203ACE2
+:100E800058121117228D538E528F518C50120F749D
+:100E9000754F0078ADE62405F58218E63400F58339
+:100EA000E020E41FE54F24F64019054FC2037C18EB
+:100EB0001233D790FF93E04401F0B2B3AC50120F5D
+:100EC0007480D078ADE62405F58218E63400F58309
+:100ED000E020E405C2037C022278ADE62405F58219
+:100EE00018E63400F583E0540F601678ADE624056B
+:100EF000F58218E63400F583E0540FF0C2037C015C
+:100F00002278AC8683088682E0AD53AE52AF511290
+:100F10000318C2037C00228D318C30121516E53186
+:100F2000600FE530B4030A7C0112250F7C81122585
+:100F30000FAC30120F74E531601A78AE86830886E4
+:100F400082E054E7F0A3A3A3A3E054E7F0AC307D24
+:100F500002120D3A78AA868308868279957A367BC2
+:100F60000A78011203FEC203E53024A1F8E654FD1D
+:100F7000F6AC30121117228C26300305123376801E
+:100F8000F87C0A123289D203E52624FD78A7F67090
+:100F90000778AE76FF0876E078A7E67D007C04252A
+:100FA000E0CD33CDDCF9FC24A078ADF6ED34FF18AC
+:100FB000F678A7E675F00AA42400FCE434FCFD787A
+:100FC000AAEDF608ECF61233222278ADE62402F5FB
+:100FD0008218E63400F583E030E72278ADE624029B
+:100FE000F58218E63400F583E0547FF078ADE6240E
+:100FF00002F58218E63400F583E04480F02278AEF2
+:101000008683088682E0547FF0AD83E5822404FC69
+:10101000E43D8C82F583E0547FF078ADE6240BF557
+:101020008218E63400F583E054F8F078AFE6240146
+:10103000F58218E63400F583E04403F078AFE62447
+:1010400005F58218E63400F583E04403F078ADE658
+:101050002405F58218E63400F583740FF02278AE8B
+:101060008683088682E0543FF0AD83E5822404FC49
+:10107000E43D8C82F583E0543FF078A7E624A8F89D
+:10108000E6FC78AFE62401F58218E63400F583EC3F
+:10109000F078A7E624A8F8E6FC78AFE62405F58208
+:1010A00018E63400F583ECF078ADE6240BF58218F1
+:1010B000E63400F583E054FB4402F52678ABE624E1
+:1010C00002F58218E63400F583E030E5034326019B
+:1010D00078ADE62405F58218E63400F583E030E0CB
+:1010E00003120FC7E526FC78ADE6240BF58218E65F
+:1010F0003400F583ECF078ADE62405F58218E6348B
+:1011000000F583740FF078AE8683088682E0448011
+:10111000F0A3A3A3A3E04480F0228C2A120F7478DA
+:10112000ABE62408F58218E63400F583E0FC78ADE0
+:10113000E6240AF58218E63400F583ECF078ABE695
+:101140002407F58218E63400F583E0FC78ADE62448
+:1011500009F58218E63400F583ECF078AA86830856
+:101160008682E0FDA3E0FCEDFE78ADE62408F58282
+:1011700018E63400F583EEF0ECFE78ADE62407F5D2
+:101180008218E63400F583EEF08C298D28C3EC94A8
+:1011900005ED940C400575277C8033D3E529940137
+:1011A000E5289403400575273C8023D3E5299481E5
+:1011B000E528940140057527188013D3E52994602C
+:1011C000E5289400400575270C8003752708AF2794
+:1011D000E4EF547C4483FF8F27E527FC78AFE624B7
+:1011E00001F58218E63400F583ECF0E527FC78AFD2
+:1011F000E62405F58218E63400F583ECF0E527FCDB
+:1012000078A7E624A8F8ECF678ADE62402F5821873
+:10121000E63400F583E0F52778ABE62402F5821882
+:10122000E63400F583A3E030E3175327C778ABE635
+:101230002405F58218E63400F583E0903686934263
+:101240002778ABE62402F58218E63400F583E03017
+:10125000E70543274080035327BF5327FB78ABE6BE
+:101260002406F58218E63400F583E0600343270482
+:101270005327FC78ABE62404F58218E63400F583A6
+:10128000E04227432780E527FC78ADE62402F5827B
+:1012900018E63400F583ECF078ADE62404F5821806
+:1012A000E63400F583E0F52778ABE62402F58218F2
+:1012B000E63400F583A3E030E1055327DF800343E4
+:1012C000272078ABE62402F58218E63400F583E0A7
+:1012D00030E4055327EF800343271078ABE6240959
+:1012E000F58218E63400F583E0B40203432702E5F3
+:1012F00027FC78ADE62404F58218E63400F583EC8B
+:10130000F078ADE62403F58218E63400F583E0F5C5
+:101310002778ABE62409F58218E63400F583E070FF
+:101320000553277F800343278078ABE62402F582AC
+:1013300018E63400F583A3E030E00543272080035E
+:101340005327DF78ABE62402F58218E63400F583F4
+:10135000E030E30543274080035327BF78ABE62402
+:1013600002F58218E63400F583E030E005432710EB
+:1013700080035327EF78ABE62402F58218E63400A9
+:10138000F583A3E030E40543270880035327F7786B
+:10139000ABE62402F58218E63400F583A3E030E5DD
+:1013A0000543270480035327FB78ABE62402F5822C
+:1013B00018E63400F583A3E030E6054327018003F7
+:1013C0005327FE78ABE62402F58218E63400F58355
+:1013D000A3E030E70543270280035327FDE527FC00
+:1013E00078ADE62403F58218E63400F583ECF0C20C
+:1013F000037C00228D278C26ED54031460037C109F
+:1014000022E527547C24FC40037C0B22E52624A102
+:10141000F8E64402F67C00228C30120F74E530248A
+:10142000A1F8E620E24FAC307D02120D3AE53024FF
+:10143000FE4428FC78AE8683088682ECF0AF83E514
+:10144000822404FEE43FFFEC8E828F83F07C038CC9
+:101450002CE52CFC78AFE62401F58218E63400F583
+:1014600083ECF0E52CFC78AFE62405F58218E63431
+:1014700000F583ECF0752D01752F48752EFFE530D2
+:1014800024FDFCE434FFFDEC7C0325E0CD33CDDC12
+:10149000F9FCE52F2CF52FE52E3DF52E78AFE6244F
+:1014A00004F58218E63400F583E054E7F52CAD2FFF
+:1014B000AE2EAF2DE4900002120320E4900006123D
+:1014C00003201201EF30E503432C10E52CFC78AF2C
+:1014D000E62404F58218E63400F583ECF012105B84
+:1014E00078ADE62406F58218E63400F583E0C20301
+:1014F000FCE53024A1F8E64404F68C2CE530540FCA
+:10150000C454F07E00FFEEEF44047D00FFEC4EFC7F
+:10151000ED4FFD121CC77C00228C2F120F74120F8E
+:10152000FB78AE8683088682E05408F0A3A3A3A3C9
+:10153000E05408F0AC2F7D02120D3AC203E52F24CF
+:10154000A1F8E654FBF67C0022123214789AECF6ED
+:10155000EC24A1F8E630E10A7D007C131225471245
+:101560003297789AE624A1F8E64401F6789AE6FCE8
+:10157000120F74789AE624FD75F00AA42414F582FB
+:10158000E434FCF58378AAE6FA08E6F97B0A7801E8
+:101590001203B078AA868308868279957A367B0A08
+:1015A00078011203FE120FC7C203789AE6FC1211EB
+:1015B000177899ECF6EC600A7D007C08122547123A
+:1015C0003297789AE6FC120F7478ADE62404F5821F
+:1015D00018E63400F583E0441054DFFC78ADE624CF
+:1015E00004F58218E63400F583ECF07899ECF6C245
+:1015F000037CC81233D7789AE6FC120F7478ADE6F4
+:101600002404F58218E63400F583E054EFF0C203B9
+:101610007CC81233D7789AE6FC120F7478ADE624B2
+:1016200004F58218E63400F583E04410F0C2037C30
+:10163000C81233D7789AE6FC120F7478ADE624040A
+:10164000F58218E63400F583E04420F0C2037CF014
+:101650001233D7789AE6FC120F7478ADE62405F5BC
+:101660008218E63400F583E030E415C203789AE688
+:1016700044107F00FE7C0712332912329702173D77
+:1016800078ADE62404F58218E63400F583E054CF03
+:10169000F0C2037CC81233D7789AE6FC120F747834
+:1016A000ADE62404F58218E63400F583E04430F01A
+:1016B000C2037CF01233D7789AE6FC120F7478AD2F
+:1016C000E62405F58218E63400F583E030E414C220
+:1016D00003789AE644107F00FE7C07123329123209
+:1016E00097805D78ADE62404F58218E63400F58332
+:1016F000E054EFF078ADE62404F58218E63400F506
+:1017000083E054DFF0789AE624FD75F00AA42414EF
+:10171000F582E434FCF583AC82AD8378AA86830835
+:101720008682ECF9EDFA7B0A78011203B0C20378E5
+:101730009AE6FC1211177D007C0B12254712329796
+:1017400022123214E490FC39F07D027C001225470D
+:10175000123297221232147C001225E012329722A4
+:10176000743C90FBE0F0743E90FBE0F0E490FC28C9
+:10177000F0228D358C34ECB401028003D34002801A
+:1017800028B402028003D34008A835E625E0F6809D
+:1017900018B404028003D3400AA835E625E025E00A
+:1017A000F68006A83576008000228C3C8D3BEDFE4D
+:1017B000ECFD7F0175660675670090FC29120477C1
+:1017C0001201EFB480028006D3500302187090FC1F
+:1017D000291204899000031201F554F0B4300280FC
+:1017E00003D3405F90FC291204899000081202176D
+:1017F000FAFDEBFE7F0190FC2C120477EECD9036C3
+:101800009FFCE493FF740193FEF9EFFA7B01EAFF7A
+:10181000E9FEECC39EED9F40259036A1E493FD7454
+:101820000193FCEDFEECFD7F01EECDFC90FC2EE083
+:10183000D39C90FC2DE09D50057566808033121975
+:101840008E802EB460028003D3400BAC3CAD3B12C3
+:1018500007828C66801BB41003B34010C3B420030E
+:10186000B34009C3B440028003D340007566818051
+:10187000008075B481028003D3406B90FC29120470
+:10188000899000031201F554F0B430028003D34074
+:101890001D90FC29120489900008120217FAFDEB32
+:1018A000FE7F0190FC2F1204771218F88036B46086
+:1018B000028003D34013753A67E4F539F538AC3C40
+:1018C000AD3B1205DE8C66801BB41003B34010C321
+:1018D000B42003B34009C3B440028003D340007571
+:1018E0006681800080028000E566FC90FC2912047D
+:1018F00089EC900002120320AC672290FC291204AC
+:10190000899000041201F5600474018001E4A2E0F2
+:10191000920190FC29120489ED2403FD50010E90E0
+:10192000FC2C12047790FC29120489900005120106
+:10193000F5F5679000041201F5540FFC7D6712174E
+:101940006FE5677004756608227566007884760016
+:101950007884E6C39567503890FC2F1204891201F1
+:10196000EFFC90FC2C120489EC12031830010E904D
+:10197000FC31E004F090FC307003E004F078840661
+:1019800090FC2EE004F090FC2D7003E004F080C089
+:101990002290FC2AE0FDA3E0FCEDFEECFD7F01EDD2
+:1019A000240AFD50010E90FC3212047790FC29129B
+:1019B00004899000041201F5540FB401028003D38E
+:1019C000401790FC321204890DED70010E90FC2F2F
+:1019D00012047778887601804EB402028003D340E7
+:1019E0001990FC32120489ED2402FD50010E90FC86
+:1019F0002F12047778887602802DB404028003D3F6
+:101A0000401990FC32120489ED2404FD50010E901F
+:101A1000FC2F12047778887604800CB400028003CF
+:101A2000D340007566082290FC29120489900005B5
+:101A30001201F5F567788576007885E6C3956740ED
+:101A400003021AF6788676007886E6C37888965080
+:101A50007690FC2C1204891201EFFC90FC321204E7
+:101A6000921201E9F45CFC1201E9F890FC2F1204D7
+:101A700089E8C0E01201EFC8D0E0C8584CFC90FCE7
+:101A80002C120489EC1203187887ECF690FC31E0F4
+:101A900004F090FC307003E004F009E970010A9052
+:101AA000FC3212048090FC29120489900004120177
+:101AB000F530E40E90FC2EE004F090FC2D7003E075
+:101AC00004F078860680817888E6FDE4FEFFEECD9E
+:101AD000FC90FC31E02CF090FC30E03DF07888E6A2
+:101AE000FDE4FEFFEECDFC90FC34E02CF090FC33E6
+:101AF000E03DF0788506021A367566002222C0E0C5
+:101B0000C0F0C082C083C0D0E8C0E0E9C0E0EAC055
+:101B1000E0EBC0E0ECC0E0EDC0E0EEC0E0EFC0E024
+:101B200090FF92E01201C01B49301B49321B58380C
+:101B30001B6A3A1B7C3E1B94441B88461BA0501B0F
+:101B4000E2521BC1541C035600001C2490FF92E07B
+:101B50007F00FE7C01123329021C34E4FF04FE7C6A
+:101B600003123329742090FFFEF0021C34E4FF04BA
+:101B7000FE7C02123329744090FFFEF0021C34E414
+:101B8000FF04FE7C04123329021C34E4FF04FE7CB3
+:101B900005123329021C34E4FF04FE7C06123329AB
+:101BA000021C3490FFA5E07D0090FBF8CDF0A3CDA2
+:101BB000F090FBF9E0FCF58390FBF8E04433FD1274
+:101BC0001CC7807390FFB5E07D0090FBFACDF0A3B9
+:101BD000CDF090FBFBE0FCF58390FBFAE04443FD85
+:101BE000121CC7805290FFA6E07D0090FBFCCDF058
+:101BF000A3CDF090FBFDE0FCF58390FBFCE04434CA
+:101C0000FD121CC7803190FFB6E07D0090FBFECD39
+:101C1000F0A3CDF090FBFFE0FCF58390FBFEE044E9
+:101C200044FD121CC7801090FF92E07D00FCED4443
+:101C3000AAFD121CC78000E490FF92F0D0E0FFD014
+:101C4000E0FED0E0FDD0E0FCD0E0FBD0E0FAD0E058
+:101C5000F9D0E0F8D0D0D083D082D0F0D0E03205F7
+:101C600081058105810581A881181818EDF608EC19
+:101C7000F690FF5AE020E70280F790FF59E07D00E0
+:101C8000A88118CDF6CD08F67D03A881E618FCE6FC
+:101C9000CC25E0CC33CCDDF9CCF6CC08F6A8811805
+:101CA000E644F8F6A881181818E6FD08E6FCA881B5
+:101CB000188683088682EDF0A3ECF0740290FF5A38
+:101CC000F0158115811581158122E5812405F581A5
+:101CD000E4A88118F6A88118181818EDF608ECF693
+:101CE00090FBF5E024F85003021DE8E4A8811818E1
+:101CF000F6A88118E6FEA88118181818E6FD08E66F
+:101D0000FC7F00EF24F8404DE4EF25E0247DF582D0
+:101D1000E434FCF583E0FBA3E06C7003FAEB6D7038
+:101D2000097401A8811818F6802BE4EF25E0247DC2
+:101D3000F582E434FCF5837A00E054F0CCF8CCCDA5
+:101D4000F9CDFB7800E954F0F9EA687002EB6970AC
+:101D5000010E0F80AEA88118EEF6A8811818181889
+:101D6000EDF608ECF6A881EFF6A8811818E6707970
+:101D7000A88118E624F74071A88118181818E654AD
+:101D80000FA881F664046017A881E664036010A8B8
+:101D90008118181818E6FD08E6FC121C5C804A7CC5
+:101DA0000A123289A88118181818E6FD08E6FC9076
+:101DB000FBF4E025E0247DF582E434FCF583EDF0CE
+:101DC000A3ECF090FBF4E0FFE4EF045407FF90FB7A
+:101DD000F4F090FBF5E004F012332290FBF6E07093
+:101DE00008E4FEFF7C0F123329802790FBF7E00404
+:101DF000F0543F701D90FBF7E044FE7D00FC90FB2B
+:101E0000F4E025E0247DF582E434FCF583EDF0A3D5
+:101E1000ECF0E58124FBF58122788B7600788C76D6
+:101E200000740190FBF6F012321490FBF5E060575D
+:101E30007C0A12328990FBF3E025E0247DF582E4F0
+:101E400034FCF583E0FDA3E0FC90FBF3E025E02407
+:101E50007DF582E434FCF583E4F0A3F090FBF3E03D
+:101E6000FFE4EF045407FF90FBF3F090FBF5E01460
+:101E7000F07889EDF608ECF61233227889E6FD0851
+:101E8000E6FC1208E580A312337690FF93E044014C
+:101E9000F0B2B3788B06B6000D788B7600788CE6BE
+:101EA000F40404788CF68082E490FBF6F090FBF565
+:101EB000E07D00FCED44CFFD121C5C123297221233
+:101EC0003214E5706449456F601590FF83E0540F4C
+:101ED0007D00D39570ED956F500512305D80031233
+:101EE000312D12329722123214E5706449456F6029
+:101EF00005123167800E90FF80E04408F090FF8368
+:101F0000E0547FF0123297221232148C54EC54F0C9
+:101F1000B41015756A357569FC756801E56A2403A6
+:101F2000F56AE5693400F569E4F557F556E556C3F9
+:101F300094015027E554540FFCAD6AAE69AF6812A6
+:101F40000E828C55EC60028012056AE56A7002050B
+:101F5000690557E5577002055680D2E554540F24A1
+:101F6000A1F8E654FEF6E554540F7F00FE7C1212F1
+:101F70003329E5551470097D007C09122547800737
+:101F8000AD577C001225471232972212321490FF6F
+:101F9000FCE04402F090FF00E030E71390FF83E0A4
+:101FA0004480F0436D8090FFFCE04401F08011908C
+:101FB000FF82E04408F0536D7F90FFFCE054FEF098
+:101FC00090FF81E04480F01225FA90FFFEE0440586
+:101FD000F090FFFCE054FDF0123297221232147C94
+:101FE000011233D778B1E64402F674FEFC04FD1208
+:101FF0001CC790FF5AE030E70280F7E4F54E754DBC
+:1020000010AC4EAD4DE54E154E7002154DEC4D60C9
+:102010000280EE438701123297221232147C0212A0
+:1020200032A378B1E654FDF61232972212321478B8
+:10203000B1E630E02C78B1E630E12678B1E6FCF587
+:102040008318E644F0FD121C5C90FFFCE04420F095
+:102050007C021233D778B1E654FDF6741A90FFFE75
+:10206000F078B1E6FCF58318E644F1FD121C5C1231
+:10207000329722756D0090FFFFE06003436D01759C
+:102080006E00E4F56CF56BE4F56F7570497484903F
+:10209000FF82F0748490FF80F0748090FF58F07499
+:1020A0008090FF5AF0AD46AF457E00EE24FE50030F
+:1020B00002213FE4EE75F007A4247FF582E434F8B2
+:1020C000F583E0FFE4EF5480FDE4EF540F14FFEDDF
+:1020D0006038E4EF75F008A42448F582E434FFF595
+:1020E000837490F0E4EF75F008A4244AF582E43498
+:1020F000FFF5837480F0E4EF75F008A4244EF582B8
+:10210000E434FFF5837480F08034E4EF75F008A4C4
+:102110002408F582E434FFF5837490F0E4EF75F061
+:1021200008A4240AF582E434FFF583E4F0E4EF75B3
+:10213000F008A4240EF582E434FFF583E4F00E02E7
+:1021400020A88D468E448F45747F90FFFDF07490DB
+:1021500090FFFCF0228C58EC24F65006E55824370A
+:10216000FC22E5582430FC22D2B0D2B1C2B41225F0
+:1021700044EC700302227F755C03AE5B7F00E55C7C
+:10218000155C6480247F5035EF2400F582E434FB35
+:10219000F583E0FE24FE501EEF7D00FCE4FB74742A
+:1021A000C39CFAEB9DFBEE7D00FCEAC39CED6480D2
+:1021B000CB64809B50028005EF2EFF80C18E5B8F29
+:1021C0005AE55C6480247F500302227FE55A248E06
+:1021D000500302227F855A5D755B00AE5AAF5B905B
+:1021E00036CAE493F55CE55C155C6480247F501886
+:1021F000EE2400F582E434FBF583E0FCEF9036CA70
+:10220000936C70040E0F80DE8E5A8F5BE55C6480E9
+:10221000247F406E755E017560E8755FFFE55D24A3
+:1022200002F55A755C07E55C334057AD60AE5FAFB1
+:102230005EE55CF5823395E0F5831201F5C4540F39
+:10224000FC122152E55A2400F582E434FBF583ECBC
+:10225000F0055A055AAD60AE5FAF5EE55CF58233BE
+:1022600095E0F5831201F5540FFC122152E55A2432
+:1022700000F582E434FBF583ECF0055A055A155C51
+:1022800080A4740290F851F090F86B79A37A367BB1
+:102290002778011203FE756A357569FC756801E4DB
+:1022A00090FF83F0748090FF81F0755902E55975B5
+:1022B000F007A4247FF582E434F8F583E07893F600
+:1022C000FC540F14FC7893ECF6E55975F007A42440
+:1022D00081F582E434F8F583E0789676FD0876E8B7
+:1022E000FC7893E675F008A42448F582E434FFF501
+:1022F00083E4F07893E675F008A4244FF582E43483
+:10230000FFF583ECF07896E6FF08E67E03CFC31373
+:10231000CF13DEF9FE7893E675F008A42449F58220
+:10232000E434FFF583EEF07893E675F008A4244AD0
+:10233000F582E434FFF5837480F07894ECF67D0048
+:102340007897E62CF618E63DF67896E6FD08E67CEA
+:1023500003CDC313CD13DCF9FC7893E675F008A424
+:10236000244DF582E434FFF583ECF07893E675F0C4
+:1023700008A4244EF582E434FFF583E4F07896E671
+:10238000FD08E6FC7893E6FF7E00EE24FE50030293
+:1023900024FEE4EE75F007A4247FF582E434F8F51A
+:1023A00083E0FFE4EF5480FAE4EF540F14FFE4EE0F
+:1023B00075F007A42481F582E434F8F583E078947D
+:1023C000F6E4EE1313548024F0F8E434FDF9E8FC4D
+:1023D000E9FD8A5AEA700302246BE4EF75F008A461
+:1023E0002448F582E434FFF583E4F07894E6FAE4D7
+:1023F000EF75F008A4244FF582E434FFF583EAF08A
+:10240000EDFBEC7A03CBC313CB13DAF9FAE4EF75E7
+:10241000F008A42449F582E434FFF583EAF07894C7
+:10242000E67B00FAEC2AFCED3BFDFBEC7A03CBC328
+:1024300013CB13DAF9FAE4EF75F008A4244DF58212
+:10244000E434FFF583EAF0E4EF75F008A4244AF5DC
+:1024500082E434FFF5837480F0E4EF75F008A4247F
+:102460004EF582E434FFF5837480F00224FAE4EF41
+:1024700075F008A42408F582E434FFF583E4F078CD
+:1024800094E6FAE4EF75F008A4240FF582E434FF33
+:10249000F583EAF0EDFBEC7A03CBC313CB13DAF947
+:1024A000FAE4EF75F008A42409F582E434FFF5831B
+:1024B000EAF07894E67B00FAEC2AFCED3BFDFBECBD
+:1024C0007A03CBC313CB13DAF9FAE4EF75F008A45F
+:1024D000240DF582E434FFF583EAF0E4EF75F008AB
+:1024E000A4240AF582E434FFF583E4F0E4EF75F008
+:1024F00008A4240EF582E434FFF583E4F00E0223F1
+:10250000878E597896EDF608ECF67893EFF6122060
+:1025100070228C26EC30E718E526540F1475F0086D
+:10252000A42448F582E434FFF583E054DFF08016FC
+:10253000E526540F1475F008A42408F582E434FF4E
+:10254000F583E054DFF0227C0022EC90FC37F08C25
+:1025500024ED2403F5257D00D39572ED957140039C
+:10256000857225E52524B75009752503740290FC72
+:1025700037F0AC2512315222E4F56CF56B12257E52
+:102580002290FC35E06573600E740490FC37F0E433
+:10259000F56B756C0380467D73E4FEFF79357AFC3C
+:1025A0007B0174057800120348E56C2403F56CE5A3
+:1025B0006B3400F56BE56CD39572E56B9571400655
+:1025C00085726C85716BD3E56C9448E56B94004023
+:1025D0000C740290FC37F0E4F56B756C03AC6C1274
+:1025E000315222EC90FC37F0E4F56CF56B8C32EC58
+:1025F000600512314380057C001231522290FF9316
+:10260000E04401F0B2B390FF04E0F54A90FF06E029
+:10261000FDA3E0ED7D00FC7D00FC90FF06E0FFA344
+:10262000E07E00FFE4FEEC4EFCED4FFDC3EC944871
+:10263000ED9400502290FF06E0FDA3E0ED7D00FC4C
+:102640007D00FC90FF06E0FFA3E07E00FFE4FEECCF
+:102650004EFCED4FFD8004E4FD7C488C728D719042
+:10266000FF02E0FDA3E0ED7D00FC7D00FC90FF0299
+:10267000E0FFA3E07E00FFE4FEEC4EF54CED4FF5ED
+:102680004B756A357569FC7568017D357EFC7F0187
+:102690007973E4FAFB74057800120348754900E584
+:1026A0004924FE4019AD6AAE69AF68E4120318050B
+:1026B000490DED70010E8D6A8E698F6880E1756A33
+:1026C000357569FC75680178B3E614184660030235
+:1026D00027927890E6FF08E6FE788EE4F608F6C3C7
+:1026E000788FE6940218E69400501DE4FEFFC3EED6
+:1026F00094E8EF940350070EBE00010F80F0788F2E
+:1027000006E61870010680D77890EFF608EEF6D24C
+:10271000B47890E6FF08E6FE788EE4F608F6C37813
+:102720008FE6941E18E69400501DE4FEFFC3EE945D
+:10273000E8EF940350070EBE00010F80F0788F067B
+:10274000E61870010680D77890EFF608EEF6C2B171
+:102750007890E6FF08E6FE788EE4F608F6C3788FF8
+:10276000E6943A18E69400501DE4FEFFC3EE94E8A8
+:10277000EF940350070EBE00010F80F0788F06E63D
+:102780001870010680D77890EFF608EEF6D2B1788F
+:10279000B2E4F608F690FF00E05460B40002800650
+:1027A000D35003022D9BE54A540FF549E54A548066
+:1027B000A2E0920290FF01E012018A000B2D962701
+:1027C000D428F22D9629FE2D962AE12B152C7C2C4F
+:1027D0007F2CBF2D3F2D6DE56D30E70EE54C454B51
+:1027E0007008E572640245716003022D9890FF0045
+:1027F000E0541FB400028003D34029E54A6003027D
+:1028000028EFAD6AAE69AF68740112031878B1E6BB
+:1028100030E00BAD6AAE69AF6874021203187C0237
+:1028200012315222B401028003D3401BE56D20E136
+:1028300007E54A60030228EFE54A24FE5003022818
+:10284000EF7C0212315222B402028006D3500302FE
+:1028500028EDE56D20E10DE54A6009E54A648060F8
+:10286000030228EFAC4A1231D940030228EFE549B0
+:10287000702530021190FF80E05408AD6AAE69AF58
+:1028800068120318800F90FF82E05408AD6AAE69A9
+:10289000AF68120318803D154930021DE54975F0F7
+:1028A00008A42448F582E434FFF583E05408AD6AB7
+:1028B000AE69AF68120318801BE54975F008A424BF
+:1028C00008F582E434FFF583E05408AD6AAE69AFE1
+:1028D00068120318AD6AAE69AF681201EF600BAD04
+:1028E0006AAE69AF6874011203187C021231522279
+:1028F0008000022D98E56D20E706E57245716003C2
+:10290000022D9890FF00E0541FB400028003D340D2
+:102910001AE54C14454B7004E54A60030229FB7824
+:10292000B1E654FEF67C0012315222B4010280035B
+:10293000D3402AE56D20E108E56D20E0030229FB84
+:10294000E56D30E004E54A700BE56D30E109E54ADC
+:1029500024FE50030229FB7C0012315222B40202F1
+:102960008006D350030229F9E54C454B6003022948
+:10297000FBAC4A1231D940030229FBE56D20E10787
+:10298000E56D20E0028077E56D30E006E549600204
+:10299000806CE549700F90FF82E054F7F090FF8063
+:1029A000E054F7F022E549B401028003D340097DE9
+:1029B000017C03120F148011B402028003D340097A
+:1029C0007D017C04120F1480001549300215E54981
+:1029D00075F008A42448F582E434FFF583E054F749
+:1029E000F08013E54975F008A42408F582E434FF6B
+:1029F000F583E054F7F07C00123152228000022D62
+:102A000098E56D20E706E57245716003022D989008
+:102A1000FF00E0541FB400028003D3401AE54C14B9
+:102A2000454B7004E54A6003022ADE78B1E64401B2
+:102A3000F67C0012315222B401028003D34029E512
+:102A40006D20E108E56D20E003022ADEE56D30E04F
+:102A500004E549700BE56D30E108E54924FE5002BC
+:102A6000807F7C0012315222B402028003D3406F77
+:102A7000E54C454B60028069AC4A1231D940028076
+:102A800060E56D20E107E56D20E0028054E54970C6
+:102A90001430020990FF80E04408F0800790FF8224
+:102AA000E04408F022E56D30E1331549300215E5C8
+:102AB0004975F008A42448F582E434FFF583E04426
+:102AC00008F08013E54975F008A42408F582E43481
+:102AD000FFF583E04408F07C00123152228002802E
+:102AE00000022D98E56D20E712E5724571700CE546
+:102AF0004A700890FF00E0541F6003022D98E54CD7
+:102B000090FFFFF090FFFFE06005436D01800353ED
+:102B10006DFE7C0012315222E56D30E70EE5724504
+:102B200071600890FF00E0541F6003022D98AD4BC8
+:102B3000E54CED7D00FC7D00FCBD00028003022C15
+:102B400077B401028003D34032E54A7005E54CFCBE
+:102B50006003022C79756A407569F8756801D3E5E0
+:102B6000729412E57194004006E4FD7C128004AC7E
+:102B700072AD718C708D6F12316722B402028003C6
+:102B8000D34059E54A6003022C79E54CFC70277567
+:102B90006A527569F8756801D3E5729419E5719404
+:102BA000004006E4FD7C198004AC72AD718C708D20
+:102BB0006F1231678025756A6B7569F8756801D386
+:102BC000E5729427E57194004006E4FD7C278004BB
+:102BD000AC72AD718C708D6F12316722B4030280BC
+:102BE00006D35003022C77E54CF549700F90FF0493
+:102BF000E0FDA3E04D6003022C79801890FB02E019
+:102C0000FDA3E0FC90FF05E06C700790FF04E06D11
+:102C100060028068E4F570F56F7F00E54914C549EE
+:102C2000600FEF2400F582E434FBF583E02FFF8092
+:102C3000EA8F4AE54A2400F582E434FBF583E07D1F
+:102C400000D39572ED95714006AC72AD71800FE5C1
+:102C50004A2400F582E434FBF583E07D00FC8C70AF
+:102C60008D6FE54A2400FCE434FBFDFEECFD7F01A2
+:102C70008D6A8E698F68123167228000022D98025A
+:102C80002D98E56D30E719E5721445717012E54A2B
+:102C9000700EE54C454B700890FF00E0541F600338
+:102CA000022D98E56D20E008E56D20E103022D98E6
+:102CB000756A6EE4F569F568E4F56F04F570123134
+:102CC0006722E56D20E727E57245717021E54A70BE
+:102CD0001DE54C6402454B600DE54C14454B600608
+:102CE000E54C454B700890FF00E0541F6003022D37
+:102CF00098E56D20E008E56D20E103022D98854CF4
+:102D00006EE56E7010436D01536DFDD2B078B2E484
+:102D1000F608F68027E56E64026007E56E1460022F
+:102D20008079536DFE436D02E56E64026005E56EC9
+:102D300014700978B2E4F60804F6C2B07C001231CF
+:102D40005222E56D30E71AE5721445717013E54AB9
+:102D5000700FE54C454B700990FF00E0541F146064
+:102D6000028038E56D20E10280317C01123152226F
+:102D7000E56D20E715E5724571700FE54C454B7028
+:102D80000990FF00E0541F146002800FE56D20E100
+:102D90000280087C00123152228000023059B44077
+:102DA000028006D3500302304F90FF01E090FC35C3
+:102DB000F0E54A90FC36F0E490FC37F0E56A240335
+:102DC000F56AE5693400F569AD4BE54C856A8285A5
+:102DD0006983CDF0A3CDF090FF01E01201C02E0673
+:102DE000012E2C022E56032E80042ECE052F0B060C
+:102DF0002F31072F57082F83092FA90B2FCF0C2F07
+:102E0000DE802FDE810000303CE56D20E7067C058A
+:102E10001225E0227D527E367F0279387AFC7B01D2
+:102E2000740878001203487D087C0012254722E5CB
+:102E30006D20E7067C051225E022E54AB403004038
+:102E400010B40500500BE54A7F00FE7C10123329B8
+:102E5000227D007C0712254722E56D20E7067C05D0
+:102E60001225E022E54AB403004010B40500500BDF
+:102E7000E54A7F00FE7C11123329227D007C071277
+:102E8000254722E56D20E7067C051225E022E54A6C
+:102E9000B405028003D3400AE4FF04FE7C0A123327
+:102EA0002922B401028003D3400AE4FF04FE7C0817
+:102EB00012332922B403004010B40500500BE54A38
+:102EC0007F00FE7C13123329227D007C07122547E8
+:102ED00022E56D20E734D3E5729448E57194005003
+:102EE00006E572457170067C021225E022E54AB4BF
+:102EF0000103B3400BC3B403004009B406005004FF
+:102F00001231FF227C071225E02212257E22E56D78
+:102F100020E71DE54AB403004010B40500500BE55E
+:102F20004A7F00FE7C16123329227C071225E022FC
+:102F300012257E22E56D20E71DE54AB4030040100E
+:102F4000B40500500BE54A7F00FE7C19123329229C
+:102F50007C071225E02212257E22E56D20E72374EE
+:102F60008190FF93F0E54AB403004010B40500508F
+:102F70000BE54A7F00FE7C17123329227C071225BD
+:102F8000E02212257E22E56D20E71DE54AB403000C
+:102F90004010B40500500BE54A7F00FE7C18123348
+:102FA00029227C071225E02212257E22E56D20E7EA
+:102FB0001DE54AB403004010B40500500BE54A7FFC
+:102FC00000FE7C15123329227C071225E0221225EF
+:102FD0007E22E56D20E7067C071225E02212257E81
+:102FE00022E56D30E72090FF00E0541F701090FF45
+:102FF00001E0B48005122575800312257E227D0034
+:103000007C051225472290FF00E0541F60067C05D6
+:103010001225E022D3E5729448E5719400500BC369
+:10302000E5729407E571940050067C031225E022B6
+:10303000E54AB405041231FF227C071225E022E59F
+:103040006D30E7087D007C05122547227C0512259E
+:10305000E022B420028003D34000800012312D22F0
+:1030600075430090FF83E0540FD395434024E5431C
+:1030700024F0F582E434FEF583E0AD6AAE69AF6812
+:1030800012031805430DED70010E8D6A8E698F686D
+:1030900080D1E5437D00FCC3E5709CF570E56F9D34
+:1030A000F56FE570456F6006E490FF83F02290FFB6
+:1030B00082E04408F0E4F56F75704990FC35E0B4A7
+:1030C00005028003D3404090FC36E0F543B405028E
+:1030D0008003D3400AE4FF04FE7C0B12332922B4A0
+:1030E00001028003D3400AE4FF04FE7C0912332965
+:1030F00022B403004010B40500500BE5437F00FEEE
+:103100007C141233292222B480004023B482005060
+:103110001E7C357DFC1217A77D008C6C8D6B90FC9E
+:1031200037E0600512312D80057C001231522222D9
+:1031300090FF83E0547FF090FF82E04408F090FF1E
+:1031400080E04408F02290FF82E04408F090FF8085
+:10315000E04408F0228C237D008C708D6F756A35F9
+:103160007569FC7568011231672290FF83E0547F16
+:10317000F0E5706449456F700122C3E5709408E57D
+:103180006F94004015752108E5217D00FCC3E570B2
+:103190009CF570E56F9DF56F8009857021E4F56FF2
+:1031A000757049752200E522C395215026AD6AAE9F
+:1031B00069AF681201EFFCE52224F8F582E434FEE1
+:1031C000F583ECF005220DED70010E8D6A8E698F8E
+:1031D0006880D3E521547F90FF81F0228C487F00E6
+:1031E000EF24FD4019E4EF75F007A4247FF582E495
+:1031F00034F8F583E065487002D3220F80E28F47F0
+:10320000C32285727085716F90FF82E054F7F09051
+:10321000FF83E0547FF022C000C001C002C006C09E
+:1032200007E5782408F8860653067F7CFF1232896A
+:103230007C007D00E57B6046FF90FD95E0547F6E4D
+:10324000700FC083C082A3E0FDA3E0FCA3157B80C8
+:1032500007A3A3A3DFE68026DF06D082D083801EEB
+:10326000E0F8A3E0F9A3E0FAD082D083E8F0A3E984
+:10327000F0A3EAF0A3C083C082A3A3A380DA123331
+:1032800022D007D006D002D001D0002285A87A75BE
+:10329000A888EC70027C3F8C7922E5782408F876C7
+:1032A0000012337680FBC000C001C002C006C00718
+:1032B000AE047CFF123289E57B6042FF90FD95E011
+:1032C000547F6E700BC083C082A3A3A3157B8007BD
+:1032D000A3A3A3DFEA8026DF06D082D08380D8E0D4
+:1032E000F8A3E0F9A3E0FAD082D083E8F0A3E9F0F4
+:1032F000A3EAF0A3C083C082A3A3A380DA7808085E
+:103300007918097C01E6547F6E700676007700809C
+:103310000608090CBC08EE123322D007D006D002F2
+:10332000D001D00022757900857AA822C0F0C08231
+:10333000C083C3E57B24E8500512337680F4EC604B
+:1033400031903651E493C39C4028C0047CFF123274
+:1033500089D004430480E57B75F003A42495F582AD
+:10336000E434FDF583ECF0EFA3F0EEA3F0057B125F
+:103370003322D083D082D0F022C0047C20D28CD2E1
+:103380008DD504FDD0042275A80075880075B8009D
+:1033900075F00075D000E4F8900000F608B800FB66
+:1033A000020000C3ED940250047D037CE8ECF4FCC1
+:1033B000EDF4FD0CBC00010D8C7F8D7E22C3EC94DE
+:1033C000BCED940250047D077CD0ECF4FCEDF4FDE0
+:1033D0000CBC00010D8C7D8D7C22EC700122C000A4
+:1033E000E5782418F8A604E5782408F8C6547FF692
+:1033F000E630E703D0002212337680F4C28C857C5D
+:103400008C857D8AD28CC0E0C0D0C0F0C082C083E1
+:10341000C000C001C002C003C004C005C006C00790
+:10342000121AFAE5782408F8E66024E5782410F802
+:10343000A681E57875F021A4248DF582E434FCF5AD
+:103440008378B4E58104C398F9E6F008A3D9FA7447
+:10345000082578F8057808E65480700CE578B407FC
+:10346000F3780875780080EFE5782410F88681E518
+:103470007875F021A4248DF582E434FCF58378B4CA
+:10348000E58104C398F9E0F608A3D9FAD007D0067D
+:10349000D005D004D003D002D001D000D083D08298
+:1034A000D0F0D0D0D0E032C0E0C0D0C000C001C069
+:1034B00002C28E857E8D857F8BD28E781979097AAE
+:1034C00007E77004A600800BE6600816E67004E7C4
+:1034D0004480F70809DAEAE579601314F579700E8B
+:1034E000E5782408F87600123322D28CD28DD002EF
+:1034F000D001D000D0D0D0E0327581B3742A90FFD3
+:1035000093F0757F30757EF8757D60757CF01205DF
+:10351000411235AA12175D90FF93E04401F0B2B357
+:103520001235D412338480DA22C0007C01EC2408E6
+:10353000F8E660090CBC08F512337680EED0002264
+:10354000C0F0C082C083C000C006C007ED2410F8E0
+:1035500076C2ED75F021A4248DF582E434FCF58368
+:10356000C082C083A3A3E4780DF0A3D8FCEC547F01
+:1035700075F002A4241DF582E5F03436F583E4935A
+:10358000FE740193F5828E83E493FE740193FFD061
+:1035900083D082EFF0A3EEF0ED2408F8EC4480F63F
+:1035A000D007D006D000D083D082D0F0227578002A
+:1035B000757B007A0879187808760077000809DAB0
+:1035C000F8E478087480447FF674014410F5897536
+:1035D000B808D2ABD2A9227581B3D28ED28CD2AF29
+:1035E000E57B6032FF90FD95E05480602478087997
+:1035F00008E0547FFA7B00E6547FB502027BFF08A7
+:10360000D9F5EB700CEAF0123526AD04AC02123598
+:103610003DA3A3A3DFD212337680C57C017D0022B7
+:10362000050004F404F804EC04E804E404F004FCE9
+:1036300004A804AC04D804DC04A404A404A404E096
+:1036400004C004B804BC04B404CC04C804C404D04A
+:1036500004D404B0190103002200480200480E30CF
+:103660001420C81AD0180A0C050602030102000132
+:10367000CE0181010000C000800060003000180011
+:1036800010000800040002000100081828380C058A
+:10369000100A0200000000000301100A02000000EE
+:1036A0000000FBE0FBF209022700010200A0FA097A
+:1036B00004000003FF00000007058102400000072E
+:1036C00005010240000007058303020001220354A4
+:1036D0000055005300420033003400310030002018
+:1036E00000200020002000200020002000200000FA
+:0336F000000000D7
+:00000001FF
diff --git a/firmware/mts_gsm.fw.ihex b/firmware/mts_gsm.fw.ihex
new file mode 100644
index 0000000..f6ad0cb
--- /dev/null
+++ b/firmware/mts_gsm.fw.ihex
@@ -0,0 +1,867 @@
+:1000000014360002001E021AF9FFFFFFFFFF023341
+:100010001DFFFFFFFFFFFFFFFFFFFFFFFFFF02339B
+:10002000C87581CE90FDE88583A012353CEC4D600B
+:100030007378AB8003760018B89CFA787F800376DB
+:100040000018B865FA78208003760018B820FA788E
+:10005000208003760018B81FFA90FDDDAE83AF82D2
+:1000600090FBF81200AA6005E4F0A380F690FDE88A
+:10007000A88290FDE8A982E8696005E4F20880F7AB
+:100080009001081200B390010C1200B390011012FD
+:1000900000B39001141200D190011A1200D1900106
+:1000A000201200D175D00012341A020126EF6582A9
+:1000B0007003EE658322E493F8740193F97402935C
+:1000C000FE740393F5828E83E869700122E493F64F
+:1000D000A30880F4E493FC740193FD740293FE740E
+:1000E0000393FF740493F8740593F58288831200D8
+:1000F000AA700122E493A3A883A9828C838D82F045
+:10010000A3AC83AD828883898280E32121049B8014
+:1001100080049BACAE049BFDE8049D049DFBF304AE
+:10012000A2049DFBF30502050280FED0F030F00929
+:1001300020F303F68010F7800D30F10920F303F26D
+:100140008004F38001F020F404FCD0E0CC22CCC089
+:10015000E0120163020154BC0005D0F0ACF022C3F0
+:1001600013DCFC02012ABF0009ED258275F001F8BD
+:10017000E622BF010FED2582F582EE3583F583750A
+:10018000F004E022ED258275F002F8E222D083D05F
+:1001900082F5F0C3E493A3C5F095F0C0E0C3D0F0BE
+:1001A000E493A395F04012A3A3C3E5F033500205F6
+:1001B000832582F58250020583740193C0E0E493A5
+:1001C000C0E022D083D082F5F0E4937009740193EB
+:1001D0007004A3A3800C74029365F06005A3A3A32D
+:1001E00080E7740193C0E0E493C0E022120264024D
+:1001F00001FB1202B80201FB1202DC0201FB30E03B
+:100200000720E302E622E72230E10720E302E222B0
+:10021000E32230E202E022E493221202DC02022313
+:100220001202B8020223ABF012022DCBC5F0CB2292
+:1002300030E01020E306E6F5F008E622E7F5F009E5
+:10024000E7192230E11020E306E2F5F008E222E3AC
+:10025000F5F009E3192230E206E0F5F0A3E022E42C
+:1002600093F5F074019322BB0003740922BB0107CC
+:1002700089828A83740422BB020789828A8374106C
+:1002800022740A22020284BB0007E92582F8740165
+:1002900022BB010DE92582F582EA3583F5837404DA
+:1002A00022BB020DE92582F582EA3583F5837410BD
+:1002B00022E92582F87402220202B8BF0005EDF897
+:1002C000740122BF01078D828E83740422BF02074E
+:1002D0008D828E83741022EDF87402220202DCBF3C
+:1002E0000007ED2582F8740122BF010DED2582F58E
+:1002F00082EE3583F583740422BF020DED2582F56D
+:1003000082EE3583F583741022ED2582F874022283
+:10031000020310C0E0120264020328C0E01202B817
+:10032000020328C0E01202DC02032830E00B20E3C5
+:1003300004D0E0F622D0E0F72230E10B20E304D035
+:10034000E0F222D0E0F322D0E0F022C9CDC9CACE3B
+:10035000CACBCFCB12035BEDF9EEFAEFFB22BB0069
+:100360002FBF000AFAEDF8E7F60809DAFA22BF0112
+:10037000128D828E83F802037809A3E7F0D8FA225F
+:10038000020383FAEDF8E7F20809DAFA2202038D94
+:10039000BB014DBF001489828A83F9EDF802039FE7
+:1003A00008A3E0F6D9FA220203B0BF01228D828EA3
+:1003B00083FB08C9C582C9CAC583CAE0A3C9C5826F
+:1003C000C9CAC583CAF0A3DBEAD8E8220203D38DE9
+:1003D000828E83F9EDF8E0F208A3D9FA220203DD58
+:1003E000BB024DBF001289828A83F9EDF80203EF48
+:1003F00008A3E493F6D9F922BF01238D828E83FBF3
+:1004000008C9C582C9CAC583CAE493A3C9C582C93C
+:10041000CAC583CAF0A3DBE9D8E722020422898295
+:100420008A83F9EDF8E493F208A3D9F922020433A0
+:10043000BF000DFAEDF8E3F60809DAFA2202043DEE
+:10044000BF01128D828E83F802044A09A3E3F0D81B
+:10045000FA22020455FAEDF8E3F20809DAFA220268
+:10046000045FE6FB08E6FA08E6F904F618700106F0
+:1004700022E6FF08E6FE08E6FD22EFF0A3EEF0A379
+:10048000EDF022EBF0A3EAF0A3E9F022E0FFA3E015
+:10049000FEA3E0FD22E0FBA3E0FAA3E0F9220000C6
+:1004A00000000000000502006105710026059800AB
+:1004B000330A0900610A750066154400610CF900F1
+:1004C0006109A9006109E000610DC000610BF10044
+:1004D000610A1C00610A510061173C0033174F008C
+:1004E000341E1400431EBF0044202C0044201A0078
+:1004F000471EE600471F8B004D1FDC004F1F080002
+:100500005832A800617CCC7DFF121CC52290FFFCF4
+:10051000E020E72DC2AFAE59AF58755A20E55A1406
+:10052000C55A6019E4FE7F05EE4FCE24FFCECF34CE
+:10053000FFCF6007E490FF92F080ED80E08E598F4E
+:10054000582212050A7D077CB71232C47D0F7C6EDB
+:100550001232DE789D7A06E4F608DAFC7A06120595
+:10056000CD7C03120E55122168E4FEFF7C0F12327F
+:100570004DD2A822123138E490FC38F090FFF0E020
+:1005800030E408740190FC39F08005E490FC39F007
+:100590007D0A7C001225461231BB2212313890FCB4
+:1005A00039E014700E90FFF0E04410F07C0012254A
+:1005B000DF801990FC39E0700E90FFF0E054EFF00E
+:1005C0007C001225DF80057C171225DF1231BB224B
+:1005D00090FFF0E054ABF090FFF0E04420F0228C6C
+:1005E000378D367882EDF608ECF6EDFEECFD7F01F6
+:1005F0009000051201F57880F67882E6FD08E6FCA9
+:10060000EDFEECFD7F019000041201F5540FFC7D1E
+:100610008012176D7880E6700DAD3AAE39AF38E4D0
+:100620001203187C082290FFF0E054FEF090FFF0D7
+:10063000E054FDF0801E7882E6FD08E6FCEDFEEC5D
+:10064000FD7F0190000812021725E0440190FFF39E
+:10065000F00206D97882E6FD08E6FCEDFEECFD7FAF
+:100660000190000612021754FE90FFF3F0802B78E1
+:1006700082E6FD08E6FCEDFEECFD7F01900008122D
+:100680000217FAEB90FFF1F01208C8400DAD3AAE38
+:1006900039AF38E41203187C18227882E6FD08E6A8
+:1006A000FCEDFEECFD7F0190000812021790FFF1B7
+:1006B000F01208C8400DAD3AAE39AF38E412031855
+:1006C0007C18227882E6FD08E6FCEDFEECFD7F0159
+:1006D000900006120217440190FFF3F07883E6249D
+:1006E00003F618E63400F67880E624FE500990FF01
+:1006F000F0E054FDF0800790FFF0E04402F0E49059
+:10070000FFF1F0788176007880E624FFFCE434FF86
+:10071000FD7881E67F00FEECD39EEF6480CD64809F
+:100720009D402F1208AD400F7881E6AD3AAE39AF4B
+:10073000381203187C182290FFF2E0FC788286833E
+:10074000088682ECF0788106A37882A68308A682C8
+:1007500080B51208AD400F7881E6AD3AAE39AF38BA
+:100760001203187C182290FFF2E0FC78828683083E
+:100770008682ECF07880E6AD3AAE39AF38120318D5
+:100780007C00228C378D367882EDF608ECF6EDFE93
+:10079000ECFD7F019000051201F57881F67882E684
+:1007A000FD08E6FCEDFEECFD7F019000041201F572
+:1007B000540FFC7D8112176D7881E670037C08224E
+:1007C00090FFF0E054FEF090FFF0E054FDF0801B4D
+:1007D0007882E6FD08E6FCEDFEECFD7F0190000866
+:1007E00012021725E090FFF3F0805B7882E6FD08A7
+:1007F000E6FCEDFEECFD7F0190000612021754FEB0
+:1008000090FFF3F080217882E6FD08E6FCEDFEEC37
+:10081000FD7F01900008120217FAEB90FFF1F01231
+:1008200008C840037C18227882E6FD08E6FCEDFE4D
+:10083000ECFD7F0190000812021790FFF1F0120802
+:10084000C840037C18227883E6240AF618E63400B0
+:10085000F6788076007881E624FFFCE434FFFD78AA
+:1008600080E67F00FEECD39EEF6480CD64809D40E7
+:100870002178828683088682E090FFF1F01208C812
+:1008800040037C1822788006788306E618700106FB
+:1008900080C390FFF0E04401F0788286830886826E
+:1008A000E090FFF1F01208C840037C18227C00227F
+:1008B00090FFF0E020E71290FFF0E030E50990FFB4
+:1008C000F0E04420F0C32280E7D32290FFF0E02044
+:1008D000E31290FFF0E030E50990FFF0E04420F0F3
+:1008E000C32280E7D3228C428D417C00ED54F0FD81
+:1008F000EC7003ED64307005753E038003753E04B3
+:10090000AC3E120F72758300858340E541540FF5AC
+:100910003FE5407004E53F64037035E53E24FD7516
+:10092000F00AA42402F582E434FCF583E030E60505
+:100930001210598019E53E249DF8E654FBF678A97B
+:10094000E62405F58218E63400F583740FF080592B
+:10095000E5407004E53F64047048E53E24FD75F011
+:100960000AA42402F582E434FCF583E030E507AC08
+:1009700042AD41121C5AE54230E21578ADE630E056
+:100980000F78ADE630E109E4FF04FE7C0412324D3D
+:1009900078A9E62406F58218E63400F583740FF092
+:1009A0008007E4FC7DEE121C5AC203221231381279
+:1009B0000F7278A9E62406F58218E63400F583E084
+:1009C00090FC38F078A9E62405F58218E63400F5A5
+:1009D00083E090FC39F0C2037D027C0012254612B0
+:1009E00031BB221231387895ECF6EC249DF8E630D4
+:1009F000E1077C131225DF800F90FC39E0FD78952C
+:100A0000E6FC1213EF1225DF1231BB2212313878C7
+:100A100095ECF67D00120F121225DF1231BB221267
+:100A200031387895ECF6EC249DF8E630E2077C133B
+:100A30001225DF801B7895E6249DF8E620E1077CEF
+:100A4000121225DF800A7895E6FC1214131225DFB6
+:100A50001231BB221231387895ECF6EC249DF8E681
+:100A600020E2077C111225DF800A7895E6FC12153A
+:100A7000141225DF1231BB221231387895ECF612B0
+:100A80000F7278A9E62409F58218E63400F583E0B0
+:100A900090FC3FF078A9E6240AF58218E63400F5C8
+:100AA00083E090FC40F078A9E62403F58218E63450
+:100AB00000F583E0FC78A9E62404F58218E634000A
+:100AC000F583E0F56278A9E62402F58218E63400A1
+:100AD000F583E0F5638C61E4EC333354017895F6EB
+:100AE0006008E56230E1037895067895E690FC4170
+:100AF000F078A7E62402F58218E63400F583E0FDDD
+:100B0000A3E0540CFCED54E68C65F564E56130E53A
+:100B100003436501E56220E50EE561547F7008E559
+:100B20006120E703436502E56130E303436510E5B7
+:100B30006130E203436520E561540360034365408F
+:100B4000E56130E103436580E56130E4034364011E
+:100B5000E56130E603436408E56220E40EE5615494
+:100B60007F7008E56120E7034364105365FB53641D
+:100B7000F9AD64E56590FC3ACDF0A3CDF0E56330C6
+:100B8000E30DE5635430C4540F90FC3DF08005E460
+:100B900090FC3DF0E563540390FC3CF0E5635404A5
+:100BA000C31390FC3EF090FC3CE0700E7D357EFC63
+:100BB0007F01740190000912014B78A9E62408F521
+:100BC0008218E63400F583E07C00FD78A9E624076E
+:100BD000F58218E63400F583E07F004CFEEF4D907F
+:100BE000FC38F0A3CEF0CEC2037D0A7C001225466D
+:100BF0001231BB221231387895ECF6789A760108DA
+:100C000076FC0876387897760C789A12046E120281
+:100C10001D7898CBF6CB08F67F00EF24EA401FE45E
+:100C2000EF25E090357EFD93CD04937899667003AF
+:100C3000ED186670067897760080030F80DC789652
+:100C4000EFF6789A12046E9000021202177898CB91
+:100C5000F6CB08F65404CB54064B60047897760B19
+:100C60007899E630E313789A12046E900005120129
+:100C7000F524FB50047897760D7899E654C07D00F2
+:100C800064C04D70047897760B789A12046E9000C9
+:100C9000041201F524FC50047897760F789A120418
+:100CA0006E9000061201F524FD50047897760E78B8
+:100CB0009A12046E9000091201F524FD50047897F1
+:100CC000760A7897E6702A7895E6FC120F72789A81
+:100CD00012046E78A7E6F978A6E6FA7B01740A7822
+:100CE00000120348C2037895E6FC1211157897ECC0
+:100CF000F67897E6FC1225DF1231BB2212313878E4
+:100D000095ECF6120F727895E624FD75F00AA4248E
+:100D100014F582E434FCF583AC82AD8378A6868337
+:100D2000088682ECF9EDFA7B0A78011203B0C2035F
+:100D30007895E6FC1211151231BB228D2B8C2AED11
+:100D400060407527017529487528FFE52A24FDFCB8
+:100D5000E434FFFDEC7C0325E0CD33CDDCF9FCE58C
+:100D6000292CF529E5283DF528AD29AE28AF2774B3
+:100D7000809000061203207480900002120320125B
+:100D80000FC5E52B14603B7527017529087528FFF1
+:100D9000E52A24FDFCE434FFFDEC7C0325E0CD33A3
+:100DA000CDDCF9FCE5292CF529E5283DF528AD2910
+:100DB000AE28AF27E4900006120320E49000021250
+:100DC0000320221231387895ECF6EC249DF8E630B9
+:100DD000E2097895E6FC121514D2007895E6FC122B
+:100DE0000F727896760090FC39E030E704789676BA
+:100DF000017896E6FD7895E6FC120D38C2033000C6
+:100E0000077895E6FC1214137C001225DF1231BB23
+:100E10002278A9E62404F58218E63400F583E0443C
+:100E200001F078A9E62404F58218E63400F583E0A1
+:100E300030E00280ED78A9E6240BF58218E6340054
+:100E4000F583E054F8F078A9E62402F58218E63438
+:100E500000F583E04480F022C2038C58120F7278B0
+:100E6000A6868308868279AF7A357B0A78011203D9
+:100E7000FE120E0EAC587D02120D38C203AC581291
+:100E80001115228D538E528F518C50120F72754F47
+:100E90000078A9E62405F58218E63400F583E02001
+:100EA000E41FE54F24F64019054FC2037C181232A7
+:100EB000FB90FF93E04401F0B2B3AC50120F72808C
+:100EC000D078A9E62405F58218E63400F583E02001
+:100ED000E405C2037C022278A9E62405F58218E61F
+:100EE0003400F583E0540F601678A9E62405F582F6
+:100EF00018E63400F583E0540FF0C2037C01227839
+:100F0000A88683088682E0AD53AE52AF5112031813
+:100F1000C2037C00228D318C30121514E531600F34
+:100F2000E530B4030A7C0112250E7C8112250EAC3B
+:100F300030120F72E531601A78AA8683088682E043
+:100F400054E7F0A3A3A3A3E054E7F0AC307D021272
+:100F50000D3878A6868308868279B97A357B0A7837
+:100F6000011203FEC203E530249DF8E654FDF6AC01
+:100F700030121115228C2630030512329A80F87C2B
+:100F80000A1231ADD203E52624FD78A3F670077866
+:100F9000AA76FF0876E078A3E67D007C0425E0CD04
+:100FA00033CDDCF9FC24A078A9F6ED34FF18F678EF
+:100FB000A3E675F00AA42400FCE434FCFD78A6ED59
+:100FC000F608ECF61232462278A9E62402F58218D9
+:100FD000E63400F583E030E72278A9E62402F582C2
+:100FE00018E63400F583E0547FF078A9E62402F592
+:100FF0008218E63400F583E04480F02278AA8683E4
+:10100000088682E0547FF0AD83E5822404FCE43D51
+:101010008C82F583E0547FF078A9E6240BF58218E2
+:10102000E63400F583E054F8F078ABE62401F5826D
+:1010300018E63400F583E04403F078ABE62405F5C8
+:101040008218E63400F583E04403F078A9E624052D
+:10105000F58218E63400F583740FF02278AA8683AF
+:10106000088682E0543FF0AD83E5822404FCE43D31
+:101070008C82F583E0543FF078A3E624A4F8E6FCE4
+:1010800078ABE62401F58218E63400F583ECF078BD
+:10109000A3E624A4F8E6FC78ABE62405F58218E67E
+:1010A0003400F583ECF078A9E6240BF58218E634D9
+:1010B00000F583E054FB4402F52678A7E62402F508
+:1010C0008218E63400F583E030E50343260178A971
+:1010D000E62405F58218E63400F583E030E00312DB
+:1010E0000FC5E526FC78A9E6240BF58218E6340046
+:1010F000F583ECF078A9E62405F58218E63400F5CE
+:1011000083740FF078AA8683088682E04480F0A377
+:10111000A3A3A3E04480F0228C2A120F7278A7E6E2
+:101120002408F58218E63400F583E0FC78A9E6246B
+:101130000AF58218E63400F583ECF078A7E6240778
+:10114000F58218E63400F583E0FC78A9E62409F579
+:101150008218E63400F583ECF078A6868308868250
+:10116000E0FDA3E0FCEDFE78A9E62408F58218E690
+:101170003400F583EEF0ECFE78A9E62407F582183A
+:10118000E63400F583EEF08C298D28C3EC9405ED50
+:10119000940C400575277C8033D3E5299401E5281C
+:1011A0009403400575273C8023D3E5299481E528E5
+:1011B000940140057527188013D3E5299460E5282C
+:1011C0009400400575270C8003752708AF27E4EFCE
+:1011D000547C4483FF8F27E527FC78ABE62401F598
+:1011E0008218E63400F583ECF0E527FC78ABE624C2
+:1011F00005F58218E63400F583ECF0E527FC78A3CA
+:10120000E624A4F8ECF678A9E62402F58218E63480
+:1012100000F583E0F52778A7E62402F58218E63486
+:1012200000F583A3E030E3175327C778A7E624052A
+:10123000F58218E63400F583E09035AA93422778CA
+:10124000A7E62402F58218E63400F583E030E705CE
+:1012500043274080035327BF5327FB78A7E6240684
+:10126000F58218E63400F583E06003432704532732
+:10127000FC78A7E62404F58218E63400F583E04202
+:1012800027432780E527FC78A9E62402F58218E6A3
+:101290003400F583ECF078A9E62404F58218E634EE
+:1012A00000F583E0F52778A7E62402F58218E634F6
+:1012B00000F583A3E030E1055327DF8003432720B7
+:1012C00078A7E62402F58218E63400F583E030E4DE
+:1012D000055327EF800343271078A7E62409F582FA
+:1012E00018E63400F583E0B40203432702E527FC47
+:1012F00078A9E62404F58218E63400F583ECF0784A
+:10130000A9E62403F58218E63400F583E0F5277892
+:10131000A7E62409F58218E63400F583E07005534A
+:10132000277F800343278078A7E62402F58218E60A
+:101330003400F583A3E030E00543272080035327E2
+:10134000DF78A7E62402F58218E63400F583E03062
+:10135000E30543274080035327BF78A7E62402F51F
+:101360008218E63400F583E030E00543271080035F
+:101370005327EF78A7E62402F58218E63400F583B8
+:10138000A3E030E40543270880035327F778A7E656
+:101390002402F58218E63400F583A3E030E5054326
+:1013A000270480035327FB78A7E62402F58218E67A
+:1013B0003400F583A3E030E605432701800353277B
+:1013C000FE78A7E62402F58218E63400F583A3E050
+:1013D00030E70543270280035327FDE527FC78A962
+:1013E000E62403F58218E63400F583ECF0C2037CB2
+:1013F00000228D278C26ED54031460037C1022E517
+:1014000027547C24FC40037C0B22E526249DF8E62F
+:101410004402F67C00228C30120F72E530249DF8D5
+:10142000E620E24FAC307D02120D38E53024FE4458
+:1014300028FC78AA8683088682ECF0AF83E58224B4
+:1014400004FEE43FFFEC8E828F83F07C038C2CE55E
+:101450002CFC78ABE62401F58218E63400F583EC29
+:10146000F0E52CFC78ABE62405F58218E63400F5AF
+:1014700083ECF0752D01752F48752EFFE53024FDA6
+:10148000FCE434FFFDEC7C0325E0CD33CDDCF9FC3E
+:10149000E52F2CF52FE52E3DF52E78ABE62404F54F
+:1014A0008218E63400F583E054E7F52CAD2FAE2E1C
+:1014B000AF2DE4900002120320E4900006120320F6
+:1014C0001201EF30E503432C10E52CFC78ABE62449
+:1014D00004F58218E63400F583ECF012105978A96F
+:1014E000E62406F58218E63400F583E0C203FCE545
+:1014F00030249DF8E64404F68C2CE530540FC45497
+:10150000F07E00FFEEEF44047D00FFEC4EFCED4F5B
+:10151000FD121CC57C00228C2F120F72120FF9785D
+:10152000AA8683088682E05408F0A3A3A3A3E0540C
+:1015300008F0AC2F7D02120D38C203E52F249DF870
+:10154000E654FBF67C00221231387896ECF6EC2457
+:101550009DF8E630E10A7D007C131225461231BB6E
+:101560007896E6249DF8E64401F67896E6FC120F9C
+:10157000727896E624FD75F00AA42414F582E4340A
+:10158000FCF58378A6E6FA08E6F97B0A78011203EF
+:10159000B078A6868308868279B97A357B0A780185
+:1015A0001203FE120FC5C2037896E6FC12111578DD
+:1015B00095ECF6EC600A7D007C081225461231BBE2
+:1015C0007896E6FC120F7278A9E62404F58218E6F4
+:1015D0003400F583E0441054DFFC78A9E62404F5D8
+:1015E0008218E63400F583ECF07895ECF6C2037CC3
+:1015F000C81232FB7896E6FC120F7278A9E6240432
+:10160000F58218E63400F583E054EFF0C2037CC89D
+:101610001232FB7896E6FC120F7278A9E62404F5E4
+:101620008218E63400F583E04410F0C2037CC8124F
+:1016300032FB7896E6FC120F7278A9E62404F58254
+:1016400018E63400F583E04420F0C2037CF0123247
+:10165000FB7896E6FC120F7278A9E62405F582184D
+:10166000E63400F583E030E415C2037896E64410D2
+:101670007F00FE7C0712324D1231BB02173B78A966
+:10168000E62404F58218E63400F583E054CFF0C276
+:10169000037CC81232FB7896E6FC120F7278A9E63A
+:1016A0002404F58218E63400F583E04430F0C203E8
+:1016B0007CF01232FB7896E6FC120F7278A9E624D1
+:1016C00005F58218E63400F583E030E414C20378AF
+:1016D00096E644107F00FE7C0712324D1231BB802B
+:1016E0005D78A9E62404F58218E63400F583E05419
+:1016F000EFF078A9E62404F58218E63400F583E0DB
+:1017000054DFF07896E624FD75F00AA42414F582DF
+:10171000E434FCF583AC82AD8378A68683088682A8
+:10172000ECF9EDFA7B0A78011203B0C2037896E671
+:10173000FC1211157D007C0B1225461231BB2212C2
+:101740003138E490FC39F07D027C001225461231DC
+:10175000BB221231387C001225DF1231BB22743CCF
+:1017600090FBE0F0743E90FBE0F0E490FC28F02267
+:101770008D358C34ECB401028003D340028028B450
+:1017800002028003D34008A835E625E0F68018B4AD
+:1017900004028003D3400AA835E625E025E0F68060
+:1017A00006A83576008000228C3C8D3BEDFEECFDDA
+:1017B0007F0175660675670090FC29120477120197
+:1017C000EFB480028006D3500302186E90FC2912F9
+:1017D00004899000031201F554F0B430028003D361
+:1017E000405F90FC29120489900008120217FAFD4C
+:1017F000EBFE7F0190FC2C120477EECD9035C3FCFC
+:10180000E493FF740193FEF9EFFA7B01EAFFE9FE2E
+:10181000ECC39EED9F40259035C5E493FD74019384
+:10182000FCEDFEECFD7F01EECDFC90FC2EE0D39CA8
+:1018300090FC2DE09D5005756680803312198C80D8
+:101840002EB460028003D3400BAC3CAD3B1207804A
+:101850008C66801BB41003B34010C3B42003B340A4
+:1018600009C3B440028003D34000756681800080C4
+:1018700075B481028003D3406B90FC2912048990D7
+:1018800000031201F554F0B430028003D3401D90E0
+:10189000FC29120489900008120217FAFDEBFE7F62
+:1018A0000190FC2F1204771218F68036B460028083
+:1018B00003D34013753A67E4F539F538AC3CAD3BDA
+:1018C0001205DC8C66801BB41003B34010C3B42037
+:1018D00003B34009C3B440028003D340007566815E
+:1018E000800080028000E566FC90FC29120489ECEF
+:1018F000900002120320AC672290FC291204899008
+:1019000000041201F5600474018001E4A2E0920178
+:1019100090FC29120489ED2403FD50010E90FC2C4B
+:1019200012047790FC291204899000051201F5F544
+:10193000679000041201F5540FFC7D6712176DE5E6
+:10194000677004756608227566007884760078846E
+:10195000E6C39567503890FC2F1204891201EFFC02
+:1019600090FC2C120489EC12031830010E90FC310B
+:10197000E004F090FC307003E004F078840690FC02
+:101980002EE004F090FC2D7003E004F080C0229063
+:10199000FC2AE0FDA3E0FCEDFEECFD7F01ED240A56
+:1019A000FD50010E90FC3212047790FC291204893C
+:1019B0009000041201F5540FB401028003D34017C4
+:1019C00090FC321204890DED70010E90FC2F120470
+:1019D0007778887601804EB402028003D340199054
+:1019E000FC32120489ED2402FD50010E90FC2F12EE
+:1019F000047778887602802DB404028003D34019DE
+:101A000090FC32120489ED2404FD50010E90FC2F4D
+:101A100012047778887604800CB400028003D340E7
+:101A2000007566082290FC291204899000051201B5
+:101A3000F5F567788576007885E6C39567400302FB
+:101A40001AF4788676007886E6C378889650769081
+:101A5000FC2C1204891201EFFC90FC321204921249
+:101A600001E9F45CFC1201E9F890FC2F120489E80A
+:101A7000C0E01201EFC8D0E0C8584CFC90FC2C121A
+:101A80000489EC1203187887ECF690FC31E004F03E
+:101A900090FC307003E004F009E970010A90FC3218
+:101AA00012048090FC291204899000041201F53080
+:101AB000E40E90FC2EE004F090FC2D7003E004F0A6
+:101AC00078860680817888E6FDE4FEFFEECDFC9006
+:101AD000FC31E02CF090FC30E03DF07888E6FDE44D
+:101AE000FEFFEECDFC90FC34E02CF090FC33E03DAA
+:101AF000F0788506021A347566002222C0E0C0F034
+:101B0000C082C083C0D0E8C0E0E9C0E0EAC0E0EB3A
+:101B1000C0E0ECC0E0EDC0E0EEC0E0EFC0E090FF60
+:101B200092E01201C01B47301B47321B56381B681E
+:101B30003A1B7A3E1B92441B86461B9E501BE0526A
+:101B40001BBF541C015600001C2290FF92E07F0036
+:101B5000FE7C0112324D021C32E4FF04FE7C0312B3
+:101B6000324D742090FFFEF0021C32E4FF04FE7C34
+:101B70000212324D744090FFFEF0021C32E4FF046A
+:101B8000FE7C0412324D021C32E4FF04FE7C05127E
+:101B9000324D021C32E4FF04FE7C0612324D021C60
+:101BA0003290FFA5E07D0090FBF8CDF0A3CDF09042
+:101BB000FBF9E0FCF58390FBF8E04433FD121CC513
+:101BC000807390FFB5E07D0090FBFACDF0A3CDF0DF
+:101BD00090FBFBE0FCF58390FBFAE04443FD121C14
+:101BE000C5805290FFA6E07D0090FBFCCDF0A3CD18
+:101BF000F090FBFDE0FCF58390FBFCE04434FD122B
+:101C00001CC5803190FFB6E07D0090FBFECDF0A3B7
+:101C1000CDF090FBFFE0FCF58390FBFEE04444FD3B
+:101C2000121CC5801090FF92E07D00FCED44AAFDDF
+:101C3000121CC58000E490FF92F0D0E0FFD0E0FEDF
+:101C4000D0E0FDD0E0FCD0E0FBD0E0FAD0E0F9D06D
+:101C5000E0F8D0D0D083D082D0F0D0E0320581053A
+:101C60008105810581A881181818EDF608ECF69019
+:101C7000FF5AE020E70280F790FF59E07D00A8813D
+:101C800018CDF6CD08F67D03A881E618FCE6CC2534
+:101C9000E0CC33CCDDF9CCF6CC08F6A88118E644CC
+:101CA000F8F6A881181818E6FD08E6FCA881188641
+:101CB00083088682EDF0A3ECF0740290FF5AF015D1
+:101CC0008115811581158122E5812405F581E4A81E
+:101CD0008118F6A88118181818EDF608ECF690FB94
+:101CE000F5E024F85003021DE6E4A8811818F6A8D0
+:101CF0008118E6FEA88118181818E6FD08E6FC7F92
+:101D000000EF24F8404DE4EF25E0247DF582E43433
+:101D1000FCF583E0FBA3E06C7003FAEB6D700974D3
+:101D200001A8811818F6802BE4EF25E0247DF582C8
+:101D3000E434FCF5837A00E054F0CCF8CCCDF9CD56
+:101D4000FB7800E954F0F9EA687002EB6970010E63
+:101D50000F80AEA88118EEF6A88118181818EDF6B5
+:101D600008ECF6A881EFF6A8811818E67079A8812A
+:101D700018E624F74071A88118181818E6540FA81F
+:101D800081F664046017A881E664036010A88118D6
+:101D9000181818E6FD08E6FC121C5A804A7C0A1244
+:101DA00031ADA88118181818E6FD08E6FC90FBF480
+:101DB000E025E0247DF582E434FCF583EDF0A3EC2E
+:101DC000F090FBF4E0FFE4EF045407FF90FBF4F025
+:101DD00090FBF5E004F012324690FBF6E07008E468
+:101DE000FEFF7C0F12324D802790FBF7E004F05489
+:101DF0003F701D90FBF7E044FE7D00FC90FBF4E09B
+:101E000025E0247DF582E434FCF583EDF0A3ECF0CD
+:101E1000E58124FBF58122788B7600788C7600743E
+:101E20000190FBF6F012313890FBF5E060577C0A28
+:101E30001231AD90FBF3E025E0247DF582E434FC23
+:101E4000F583E0FDA3E0FC90FBF3E025E0247DF5C5
+:101E500082E434FCF583E4F0A3F090FBF3E0FFE4CC
+:101E6000EF045407FF90FBF3F090FBF5E014F078DB
+:101E700089EDF608ECF61232467889E6FD08E6FCB4
+:101E80001208E380A312329A90FF93E04401F0B26B
+:101E9000B3788B06B60011788B7600788CE6F40464
+:101EA00004A2E092B4788CF6021E25E490FBF6F0D2
+:101EB00090FBF5E07D00FCED44CFFD121C5A123181
+:101EC000BB22123138E5706449456F601590FF837D
+:101ED000E0540F7D00D39570ED956F5005122F8162
+:101EE00080031230511231BB22123138E57064493F
+:101EF000456F600512308B800E90FF80E04408F043
+:101F000090FF83E0547FF01231BB221231388C54A1
+:101F1000EC54F0B41015756A357569FC756801E507
+:101F20006A2403F56AE5693400F569E4F557F55666
+:101F3000E556C394015027E554540FFCAD6AAE69D1
+:101F4000AF68120E808C55EC60028012056AE56A5B
+:101F5000700205690557E5577002055680D2E554B1
+:101F6000540F249DF8E654FEF6E554540F7F00FE0E
+:101F70007C1212324DE5551470097D007C09122542
+:101F8000468007AD577C001225461231BB22123124
+:101F90003890FFFCE04402F090FF00E030E713903F
+:101FA000FF83E04480F0436D8090FFFCE04401F04B
+:101FB000801190FF82E04408F0536D7F90FFFCE0B9
+:101FC00054FEF090FF81E04480F01225F990FFFE6E
+:101FD000E04405F090FFFCE054FDF01231BB22120A
+:101FE00031387C011232FB78ADE64402F674FEFC17
+:101FF00004FD121CC590FF5AE030E70280F7E4F5BB
+:102000004E754D10AC4EAD4DE54E154E7002154D52
+:10201000EC4D600280EE4387011231BB2212313851
+:102020007C021231C778ADE654FDF61231BB2212A4
+:10203000313878ADE630E02C78ADE630E12678AD89
+:10204000E6FCF58318E644F0FD121C5A90FFFCE014
+:102050004420F07C021232FB78ADE654FDF6741A8F
+:1020600090FFFEF078ADE6FCF58318E644F1FD1232
+:102070001C5A1231BB22756D0090FFFFE0600343D4
+:102080006D01756E00E4F56CF56BE4F56F757049E4
+:10209000748490FF82F0748490FF80F0748090FFCD
+:1020A00058F0748090FF5AF0AD46AF457E00EE24A4
+:1020B000FE5003022142E4EE75F007A4247FF5826E
+:1020C000E434F8F583E0FFE4EF5480FDE4EF540FCF
+:1020D00014FFED6038E4EF75F008A42448F582E4BD
+:1020E00034FFF5837490F0E4EF75F008A4244AF50A
+:1020F00082E434FFF5837480F0E4EF75F008A424E3
+:102100004EF582E434FFF5837480F08034E4EF759B
+:10211000F008A42408F582E434FFF5837490F0E419
+:10212000EF75F008A4240AF582E434FFF583E4F0A7
+:10213000E4EF75F008A4240EF582E434FFF583E49F
+:10214000F00E0220AB8D468E448F45747F90FFFDCC
+:10215000F0749090FFFCF0228C58EC24F65006E5C9
+:10216000582437FC22E5582430FC22D2B0122543F3
+:10217000EC700302227E755C03AE5B7F00E55C15AC
+:102180005C6480247F5035EF2400F582E434FBF555
+:1021900083E0FE24FE501EEF7D00FCE4FB7474C35C
+:1021A0009CFAEB9DFBEE7D00FCEAC39CED6480CBCA
+:1021B00064809B50028005EF2EFF80C18E5B8F5A9A
+:1021C000E55C6480247F500302227EE55A248E5011
+:1021D0000302227E855A5D755B00AE5AAF5B903577
+:1021E000EEE493F55CE55C155C6480247F5018EEAA
+:1021F0002400F582E434FBF583E0FCEF9035EE93A8
+:102200006C70040E0F80DE8E5A8F5BE55C64802458
+:102210007F406E755E017560E8755FFFE55D2402C5
+:10222000F55A755C07E55C334057AD60AE5FAF5E55
+:10223000E55CF5823395E0F5831201F5C4540FFC9B
+:10224000122155E55A2400F582E434FBF583ECF0C5
+:10225000055A055AAD60AE5FAF5EE55CF582339519
+:10226000E0F5831201F5540FFC122155E55A2400C4
+:10227000F582E434FBF583ECF0055A055A155C80D1
+:10228000A4740290F851F090F86B79C77A357B27E7
+:1022900078011203FE756A357569FC756801E49072
+:1022A000FF83F0748090FF81F0755902E55975F055
+:1022B00007A4247FF582E434F8F583E0788FF6FCF8
+:1022C000540F14FC788FECF6E55975F007A42481BF
+:1022D000F582E434F8F583E0789276FD0876E8FC40
+:1022E000788FE675F008A42448F582E434FFF5837E
+:1022F000E4F0788FE675F008A4244FF582E434FF0B
+:10230000F583ECF07892E6FF08E67E03CFC313CFA7
+:1023100013DEF9FE788FE675F008A42449F582E40F
+:1023200034FFF583EEF0788FE675F008A4244AF5C3
+:1023300082E434FFF5837480F07890ECF67D0078C9
+:1023400093E62CF618E63DF67892E6FD08E67C0367
+:10235000CDC313CD13DCF9FC788FE675F008A42407
+:102360004DF582E434FFF583ECF0788FE675F008E4
+:10237000A4244EF582E434FFF583E4F07892E6FD80
+:1023800008E6FC788FE6FF7E00EE24FE5003022470
+:10239000FDE4EE75F007A4247FF582E434F8F583BC
+:1023A000E0FFE4EF5480FAE4EF540F14FFE4EE751D
+:1023B000F007A42481F582E434F8F583E07890F600
+:1023C000E4EE1313548024F0F8E434FDF9E8FCE95A
+:1023D000FD8A5AEA700302246AE4EF75F008A42427
+:1023E00048F582E434FFF583E4F07890E6FAE4EF10
+:1023F00075F008A4244FF582E434FFF583EAF0ED8C
+:10240000FBEC7A03CBC313CB13DAF9FAE4EF75F0E4
+:1024100008A42449F582E434FFF583EAF07890E6D5
+:102420007B00FAEC2AFCED3BFDFBEC7A03CBC313FB
+:10243000CB13DAF9FAE4EF75F008A4244DF582E441
+:1024400034FFF583EAF0E4EF75F008A4244AF5823E
+:10245000E434FFF5837480F0E4EF75F008A4244EB3
+:10246000F582E434FFF5837480F00224F9E4EF751B
+:10247000F008A42408F582E434FFF583E4F07890B2
+:10248000E6FAE4EF75F008A4240FF582E434FFF5D2
+:1024900083EAF0EDFBEC7A03CBC313CB13DAF9FA42
+:1024A000E4EF75F008A42409F582E434FFF583EA2B
+:1024B000F07890E67B00FAEC2AFCED3BFDFBEC7A31
+:1024C00003CBC313CB13DAF9FAE4EF75F008A424B5
+:1024D0000DF582E434FFF583EAF0E4EF75F008A42B
+:1024E000240AF582E434FFF583E4F0E4EF75F008A4
+:1024F000A4240EF582E434FFF583E4F00E02238673
+:102500008E597892EDF608ECF6788FEFF61220737C
+:10251000228C26EC30E718E526540F1475F008A439
+:102520002448F582E434FFF583E054DFF08016E5BB
+:1025300026540F1475F008A42408F582E434FFF53E
+:1025400083E054DFF0227C0022EC90FC37F08C24F6
+:10255000ED2403F5257D00D39572ED95714003853B
+:102560007225E52524B75009752503740290FC37C0
+:10257000F0AC2512307622E4F56CF56B12257D2245
+:1025800090FC35E06573600E740490FC37F0E4F560
+:102590006B756C0380467D73E4FEFF79357AFC7BB6
+:1025A0000174057800120348E56C2403F56CE56BB3
+:1025B0003400F56BE56CD39572E56B95714006853B
+:1025C000726C85716BD3E56C9448E56B9400400C9C
+:1025D000740290FC37F0E4F56B756C03AC6C123050
+:1025E0007622EC90FC37F0E4F56CF56B8C32EC6005
+:1025F0000512306780057C001230762290FF93E050
+:102600004401F0B2B390FF04E0F54A90FF06E0FD0C
+:10261000A3E0ED7D00FC7D00FC90FF06E0FFA3E061
+:102620007E00FFE4FEEC4EFCED4FFDC3EC9448ED64
+:102630009400502290FF06E0FDA3E0ED7D00FC7DBC
+:1026400000FC90FF06E0FFA3E07E00FFE4FEEC4EFE
+:10265000FCED4FFD8004E4FD7C488C728D7190FF91
+:1026600002E0FDA3E0ED7D00FC7D00FC90FF02E0B8
+:10267000FFA3E07E00FFE4FEEC4EF54CED4FF54B82
+:10268000756A357569FC7568017D357EFC7F017959
+:1026900073E4FAFB74057800120348754900E549B4
+:1026A00024FE4019AD6AAE69AF68E412031805490B
+:1026B0000DED70010E8D6A8E698F6880E1756A3547
+:1026C0007569FC75680190FF00E05460B4000280F9
+:1026D00006D35003022CBFE54A540FF549E54A548E
+:1026E00080A2E0920290FF01E012018A000B2CBA56
+:1026F000270528232CBA292F2CBA2A122A462BADBB
+:102700002BB02BF02C632C91E56D30E70EE54C459A
+:102710004B7008E572640245716003022CBC90FFA7
+:1027200000E0541FB400028003D34029E54A60034F
+:10273000022820AD6AAE69AF68740112031878AD43
+:10274000E630E00BAD6AAE69AF6874021203187C24
+:102750000212307622B401028003D3401BE56D20C3
+:10276000E107E54A6003022820E54A24FE500302FF
+:1027700028207C0212307622B402028006D3500355
+:1027800002281EE56D20E10DE54A6009E54A6480F6
+:102790006003022820AC4A1230FD4003022820E5E5
+:1027A00049702530021190FF80E05408AD6AAE698F
+:1027B000AF68120318800F90FF82E05408AD6AAE34
+:1027C00069AF68120318803D154930021DE549754F
+:1027D000F008A42448F582E434FFF583E05408AD02
+:1027E0006AAE69AF68120318801BE54975F008A44A
+:1027F0002408F582E434FFF583E05408AD6AAE693D
+:10280000AF68120318AD6AAE69AF681201EF600BD2
+:10281000AD6AAE69AF6874011203187C021230769B
+:10282000228000022CBCE56D20E706E57245716050
+:1028300003022CBC90FF00E0541FB400028003D3BD
+:10284000401AE54C14454B7004E54A600302292CFC
+:1028500078ADE654FEF67C0012307622B401028098
+:1028600003D3402AE56D20E108E56D20E00302294D
+:102870002CE56D30E004E54A700BE56D30E109E5CB
+:102880004A24FE500302292C7C0012307622B40226
+:10289000028006D3500302292AE54C454B6003020F
+:1028A000292CAC4A1230FD400302292CE56D20E1B1
+:1028B00007E56D20E0028077E56D30E006E54960D0
+:1028C00002806CE549700F90FF82E054F7F090FFB2
+:1028D00080E054F7F022E549B401028003D34009B7
+:1028E0007D017C03120F128011B402028003D340D9
+:1028F000097D017C04120F1280001549300215E594
+:102900004975F008A42448F582E434FFF583E054C7
+:10291000F7F08013E54975F008A42408F582E43443
+:10292000FFF583E054F7F07C00123076228000023D
+:102930002CBCE56D20E706E57245716003022CBCF6
+:1029400090FF00E0541FB400028003D3401AE54C0E
+:1029500014454B7004E54A6003022A0F78ADE64443
+:1029600001F67C0012307622B401028003D34029A4
+:10297000E56D20E108E56D20E003022A0FE56D30EA
+:10298000E004E549700BE56D30E108E54924FE50AF
+:1029900002807F7C0012307622B402028003D34092
+:1029A0006FE54C454B60028069AC4A1230FD400235
+:1029B0008060E56D20E107E56D20E0028054E54987
+:1029C000701430020990FF80E04408F0800790FF07
+:1029D00082E04408F022E56D30E1331549300215FC
+:1029E000E54975F008A42448F582E434FFF583E056
+:1029F0004408F08013E54975F008A42408F582E442
+:102A000034FFF583E04408F07C0012307622800227
+:102A10008000022CBCE56D20E712E5724571700C58
+:102A2000E54A700890FF00E0541F6003022CBCE5EB
+:102A30004C90FFFFF090FFFFE06005436D018003C5
+:102A4000536DFE7C0012307622E56D30E70EE572A4
+:102A50004571600890FF00E0541F6003022CBCAD7C
+:102A60004BE54CED7D00FC7D00FCBD0002800302C7
+:102A70002BA8B401028003D34032E54A7005E54C2F
+:102A8000FC6003022BAA756A407569F8756801D36A
+:102A9000E5729412E57194004006E4FD7C12800416
+:102AA000AC72AD718C708D6F12308B22B4020280CB
+:102AB00003D34059E54A6003022BAAE54CFC70277A
+:102AC000756A527569F8756801D3E5729419E571F4
+:102AD00094004006E4FD7C198004AC72AD718C70EA
+:102AE0008D6F12308B8025756A6B7569F87568017A
+:102AF000D3E5729427E57194004006E4FD7C2780BD
+:102B000004AC72AD718C708D6F12308B22B40302E5
+:102B10008006D35003022BA8E54CF549700F90FFB7
+:102B200004E0FDA3E04D6003022BAA801890FB0295
+:102B3000E0FDA3E0FC90FF05E06C700790FF04E06F
+:102B40006D60028068E4F570F56F7F00E54914C59B
+:102B500049600FEF2400F582E434FBF583E02FFF9A
+:102B600080EA8F4AE54A2400F582E434FBF583E0ED
+:102B70007D00D39572ED95714006AC72AD71800FFA
+:102B8000E54A2400F582E434FBF583E07D00FC8C0B
+:102B9000708D6FE54A2400FCE434FBFDFEECFD7F04
+:102BA000018D6A8E698F6812308B228000022CBCE6
+:102BB000022CBCE56D30E719E5721445717012E521
+:102BC0004A700EE54C454B700890FF00E0541F60C2
+:102BD00003022CBCE56D20E008E56D20E103022C2A
+:102BE000BC756A6EE4F569F568E4F56F04F570127A
+:102BF000308B22E56D20E727E57245717021E54AAB
+:102C0000701DE54C6402454B600DE54C14454B606E
+:102C100006E54C454B700890FF00E0541F6003022E
+:102C20002CBCE56D20E008E56D20E103022CBC859D
+:102C30004C6EE56E700A436D01536DFDD2B080207D
+:102C4000E56E64026007E56E1460028072536DFEEB
+:102C5000436D02E56E64026005E56E147002C2B059
+:102C60007C0012307622E56D30E71AE5721445716A
+:102C70007013E54A700FE54C454B700990FF00E07A
+:102C8000541F1460028038E56D20E10280317C0120
+:102C900012307622E56D20E715E5724571700FE57B
+:102CA0004C454B700990FF00E0541F146002800FE8
+:102CB000E56D20E10280087C00123076228000025F
+:102CC0002F7DB440028006D35003022F7390FF0182
+:102CD000E090FC35F0E54A90FC36F0E490FC37F0EB
+:102CE000E56A2403F56AE5693400F569AD4BE54C06
+:102CF000856A82856983CDF0A3CDF090FF01E01253
+:102D000001C02D2A012D50022D7A032DA4042DF28D
+:102D1000052E2F062E55072E7B082EA7092ECD0B2C
+:102D20002EF30C2F02802F028100002F60E56D2012
+:102D3000E7067C051225DF227D767E357F02793815
+:102D40007AFC7B01740878001203487D087C00122D
+:102D5000254622E56D20E7067C051225DF22E54A9F
+:102D6000B403004010B40500500BE54A7F00FE7C20
+:102D70001012324D227D007C0712254622E56D207F
+:102D8000E7067C051225DF22E54AB403004010B4B3
+:102D90000500500BE54A7F00FE7C1112324D227D6A
+:102DA000007C0712254622E56D20E7067C051225EA
+:102DB000DF22E54AB405028003D3400AE4FF04FEA3
+:102DC0007C0A12324D22B401028003D3400AE4FF90
+:102DD00004FE7C0812324D22B403004010B40500FA
+:102DE000500BE54A7F00FE7C1312324D227D007CA1
+:102DF0000712254622E56D20E734D3E5729448E5B5
+:102E00007194005006E572457170067C021225DF50
+:102E100022E54AB40103B3400BC3B403004009B434
+:102E200006005004123123227C071225DF221225CE
+:102E30007D22E56D20E71DE54AB403004010B4058E
+:102E400000500BE54A7F00FE7C1612324D227C07B3
+:102E50001225DF2212257D22E56D20E71DE54AB40B
+:102E600003004010B40500500BE54A7F00FE7C19BA
+:102E700012324D227C071225DF2212257D22E56DBC
+:102E800020E723748190FF93F0E54AB403004010DB
+:102E9000B40500500BE54A7F00FE7C1712324D222C
+:102EA0007C071225DF2212257D22E56D20E71DE536
+:102EB0004AB403004010B40500500BE54A7F00FE01
+:102EC0007C1812324D227C071225DF2212257D222A
+:102ED000E56D20E71DE54AB403004010B40500503D
+:102EE0000BE54A7F00FE7C1512324D227C0712252D
+:102EF000DF2212257D22E56D20E7067C071225DF03
+:102F00002212257D22E56D30E72090FF00E0541F5E
+:102F1000701090FF01E0B480051225748003122523
+:102F20007D227D007C051225462290FF00E0541F83
+:102F300060067C051225DF22D3E5729448E5719482
+:102F400000500BC3E5729407E571940050067C03B2
+:102F50001225DF22E54AB40504123123227C071230
+:102F600025DF22E56D30E7087D007C05122546222D
+:102F70007C051225DF22B420028003D340008000AC
+:102F80001230512275430090FF83E0540FD39543D4
+:102F90004024E54324F0F582E434FEF583E0AD6A95
+:102FA000AE69AF6812031805430DED70010E8D6A0E
+:102FB0008E698F6880D1E5437D00FCC3E5709CF588
+:102FC00070E56F9DF56FE570456F6006E490FF83D7
+:102FD000F02290FF82E04408F0E4F56F75704990AC
+:102FE000FC35E0B405028003D3404090FC36E0F5A8
+:102FF00043B405028003D3400AE4FF04FE7C0B12B5
+:10300000324D22B401028003D3400AE4FF04FE7C67
+:103010000912324D22B403004010B40500500BE5F4
+:10302000437F00FE7C1412324D2222B480004023E4
+:10303000B48200501E7C357DFC1217A57D008C6C7F
+:103040008D6B90FC37E0600512305180057C0012DA
+:103050003076222290FF83E0547FF090FF82E0449C
+:1030600008F090FF80E04408F02290FF82E04408DE
+:10307000F090FF80E04408F0228C237D008C708D5E
+:103080006F756A357569FC75680112308B2290FF87
+:1030900083E0547FF0E5706449456F700122C3E519
+:1030A000709408E56F94004015752108E5217D00B6
+:1030B000FCC3E5709CF570E56F9DF56F8009857028
+:1030C00021E4F56F757049752200E522C395215002
+:1030D00026AD6AAE69AF681201EFFCE52224F8F56F
+:1030E00082E434FEF583ECF005220DED70010E8DC7
+:1030F0006A8E698F6880D3E521547F90FF81F0222A
+:103100008C487F00EF24FD4019E4EF75F007A424FC
+:103110007FF582E434F8F583E065487002D3220F2E
+:1031200080E28F47C32285727085716F90FF82E0C5
+:1031300054F7F090FF83E0547FF022C000C001C03C
+:1031400002C006C007E5782408F8860653067F7C8F
+:10315000FF1231AD7C007D00E57B6046FF90FD9560
+:10316000E0547F6E700FC083C082A3E0FDA3E0FC3B
+:10317000A3157B8007A3A3A3DFE68026DF06D0820A
+:10318000D083801EE0F8A3E0F9A3E0FAD082D083D8
+:10319000E8F0A3E9F0A3EAF0A3C083C082A3A3A34D
+:1031A00080DA123246D007D006D002D001D00022F9
+:1031B00085A87A75A888EC70027C3F8C7922E57826
+:1031C0002408F8760012329A80FBC000C001C002C9
+:1031D000C006C007AE047CFF1231ADE57B6042FF44
+:1031E00090FD95E0547F6E700BC083C082A3A3A3B3
+:1031F000157B8007A3A3A3DFEA8026DF06D082D059
+:103200008380D8E0F8A3E0F9A3E0FAD082D083E885
+:10321000F0A3E9F0A3EAF0A3C083C082A3A3A38034
+:10322000DA7808087918097C01E6547F6E70067612
+:10323000007700800608090CBC08EE123246D00761
+:10324000D006D002D001D00022757900857AA8225C
+:10325000C0F0C082C083C3E57B24E8500512329AD7
+:1032600080F4EC6031903575E493C39C4028C00431
+:103270007CFF1231ADD004430480E57B75F003A4DC
+:103280002495F582E434FDF583ECF0EFA3F0EEA392
+:10329000F0057B123246D083D082D0F022C0047C6D
+:1032A00020D28CD28DD504FDD0042275A80075885B
+:1032B0000075B80075F00075D000E4F8900000F6D5
+:1032C00008B800FB020000C3ED940250047D037CAB
+:1032D000E8ECF4FCEDF4FD0CBC00010D8C7F8D7E60
+:1032E00022C3EC94BCED940250047D077CD0ECF436
+:1032F000FCEDF4FD0CBC00010D8C7D8D7C22EC708E
+:103300000122C000E5782418F8A604E5782408F81E
+:10331000C6547FF6E630E703D0002212329A80F4DA
+:10332000C28C857C8C857D8AD28CC0E0C0D0C0F0F8
+:10333000C082C083C000C001C002C003C004C00579
+:10334000C006C007121AF8E5782408F8E66024E5FC
+:10335000782410F8A681E57875F021A4248DF582F3
+:10336000E434FCF58378AEE58104C398F9E6F0080F
+:10337000A3D9FA74082578F8057808E65480700C0B
+:10338000E578B407F3780875780080EFE5782410C5
+:10339000F88681E57875F021A4248DF582E434FC6B
+:1033A000F58378AEE58104C398F9E0F608A3D9FA6D
+:1033B000D007D006D005D004D003D002D001D00071
+:1033C000D083D082D0F0D0D0D0E032C0E0C0D0C026
+:1033D00000C001C002C28E857E8D857F8BD28E7823
+:1033E0001979097A07E77004A600800BE6600816D1
+:1033F000E67004E74480F70809DAEAE57960131417
+:10340000F579700EE5782408F87600123246D28CF1
+:10341000D28DD002D001D000D0D0D0E0327581ADB5
+:10342000742A90FF93F0757F30757EF8757D607516
+:103430007CF012053F1234CE12175B90FF93E044EC
+:1034400001F0B2B31234F81232A880DA22C0007C44
+:1034500001EC2408F8E660090CBC08F512329A80E9
+:10346000EED00022C0F0C082C083C000C006C007FA
+:10347000ED2410F876BCED75F021A4248DF582E4DE
+:1034800034FCF583C082C083A3A3E4780DF0A3D8F5
+:10349000FCEC547F75F002A42441F582E5F034354C
+:1034A000F583E493FE740193F5828E83E493FE74B6
+:1034B0000193FFD083D082EFF0A3EEF0ED2408F863
+:1034C000EC4480F6D007D006D000D083D082D0F074
+:1034D00022757800757B007A08791878087600776D
+:1034E000000809DAF8E478087480447FF67401442F
+:1034F00010F58975B808D2ABD2A9227581ADD28EEC
+:10350000D28CD2AFE57B6032FF90FD95E0548060B5
+:103510002478087908E0547FFA7B00E6547FB502EE
+:10352000027BFF08D9F5EB700CEAF012344AAD04C7
+:10353000AC02123461A3A3A3DFD212329A80C57CFD
+:10354000017D002204FE04F204F604EA04E604E22B
+:1035500004EE04FA04A604AA04D604DA04A204A21F
+:1035600004A204DE04BE04B604BA04B204CA04C64B
+:1035700004C204CE04D204AE1901030022004802A2
+:1035800000480E301420C81AD0180A0C0506020391
+:1035900001020001CE0181010000C0008000600036
+:1035A0003000180010000800040002000100081894
+:1035B00028380C05100A0200000000000301100A60
+:1035C000020000000000FBE0FBF2090227000102FC
+:1035D00000A0FA0904000003FF00000007058102B3
+:1035E00040000007050102400000070583030200B8
+:1035F00001220354005500530042003300340031CF
+:1036000000300020002000200020002000200020AA
+:073610000020000000000093
+:00000001FF
diff --git a/fs/dlm/debug_fs.c b/fs/dlm/debug_fs.c
index 2f107d1..1d1d274 100644
--- a/fs/dlm/debug_fs.c
+++ b/fs/dlm/debug_fs.c
@@ -1,7 +1,7 @@
/******************************************************************************
*******************************************************************************
**
-** Copyright (C) 2005-2008 Red Hat, Inc. All rights reserved.
+** Copyright (C) 2005-2009 Red Hat, Inc. All rights reserved.
**
** This copyrighted material is made available to anyone wishing to use,
** modify, copy, or redistribute it subject to the terms and conditions
@@ -25,19 +25,6 @@ static struct mutex debug_buf_lock;
static struct dentry *dlm_root;
-struct rsb_iter {
- int entry;
- int format;
- int header;
- struct dlm_ls *ls;
- struct list_head *next;
- struct dlm_rsb *rsb;
-};
-
-/*
- * dump all rsb's in the lockspace hash table
- */
-
static char *print_lockmode(int mode)
{
switch (mode) {
@@ -60,13 +47,13 @@ static char *print_lockmode(int mode)
}
}
-static void print_format1_lock(struct seq_file *s, struct dlm_lkb *lkb,
- struct dlm_rsb *res)
+static int print_format1_lock(struct seq_file *s, struct dlm_lkb *lkb,
+ struct dlm_rsb *res)
{
seq_printf(s, "%08x %s", lkb->lkb_id, print_lockmode(lkb->lkb_grmode));
- if (lkb->lkb_status == DLM_LKSTS_CONVERT
- || lkb->lkb_status == DLM_LKSTS_WAITING)
+ if (lkb->lkb_status == DLM_LKSTS_CONVERT ||
+ lkb->lkb_status == DLM_LKSTS_WAITING)
seq_printf(s, " (%s)", print_lockmode(lkb->lkb_rqmode));
if (lkb->lkb_nodeid) {
@@ -80,33 +67,42 @@ static void print_format1_lock(struct seq_file *s, struct dlm_lkb *lkb,
if (lkb->lkb_wait_type)
seq_printf(s, " wait_type: %d", lkb->lkb_wait_type);
- seq_printf(s, "\n");
+ return seq_printf(s, "\n");
}
static int print_format1(struct dlm_rsb *res, struct seq_file *s)
{
struct dlm_lkb *lkb;
int i, lvblen = res->res_ls->ls_lvblen, recover_list, root_list;
+ int rv;
lock_rsb(res);
- seq_printf(s, "\nResource %p Name (len=%d) \"", res, res->res_length);
+ rv = seq_printf(s, "\nResource %p Name (len=%d) \"",
+ res, res->res_length);
+ if (rv)
+ goto out;
+
for (i = 0; i < res->res_length; i++) {
if (isprint(res->res_name[i]))
seq_printf(s, "%c", res->res_name[i]);
else
seq_printf(s, "%c", '.');
}
+
if (res->res_nodeid > 0)
- seq_printf(s, "\" \nLocal Copy, Master is node %d\n",
- res->res_nodeid);
+ rv = seq_printf(s, "\" \nLocal Copy, Master is node %d\n",
+ res->res_nodeid);
else if (res->res_nodeid == 0)
- seq_printf(s, "\" \nMaster Copy\n");
+ rv = seq_printf(s, "\" \nMaster Copy\n");
else if (res->res_nodeid == -1)
- seq_printf(s, "\" \nLooking up master (lkid %x)\n",
- res->res_first_lkid);
+ rv = seq_printf(s, "\" \nLooking up master (lkid %x)\n",
+ res->res_first_lkid);
else
- seq_printf(s, "\" \nInvalid master %d\n", res->res_nodeid);
+ rv = seq_printf(s, "\" \nInvalid master %d\n",
+ res->res_nodeid);
+ if (rv)
+ goto out;
/* Print the LVB: */
if (res->res_lvbptr) {
@@ -119,52 +115,66 @@ static int print_format1(struct dlm_rsb *res, struct seq_file *s)
}
if (rsb_flag(res, RSB_VALNOTVALID))
seq_printf(s, " (INVALID)");
- seq_printf(s, "\n");
+ rv = seq_printf(s, "\n");
+ if (rv)
+ goto out;
}
root_list = !list_empty(&res->res_root_list);
recover_list = !list_empty(&res->res_recover_list);
if (root_list || recover_list) {
- seq_printf(s, "Recovery: root %d recover %d flags %lx "
- "count %d\n", root_list, recover_list,
- res->res_flags, res->res_recover_locks_count);
+ rv = seq_printf(s, "Recovery: root %d recover %d flags %lx "
+ "count %d\n", root_list, recover_list,
+ res->res_flags, res->res_recover_locks_count);
+ if (rv)
+ goto out;
}
/* Print the locks attached to this resource */
seq_printf(s, "Granted Queue\n");
- list_for_each_entry(lkb, &res->res_grantqueue, lkb_statequeue)
- print_format1_lock(s, lkb, res);
+ list_for_each_entry(lkb, &res->res_grantqueue, lkb_statequeue) {
+ rv = print_format1_lock(s, lkb, res);
+ if (rv)
+ goto out;
+ }
seq_printf(s, "Conversion Queue\n");
- list_for_each_entry(lkb, &res->res_convertqueue, lkb_statequeue)
- print_format1_lock(s, lkb, res);
+ list_for_each_entry(lkb, &res->res_convertqueue, lkb_statequeue) {
+ rv = print_format1_lock(s, lkb, res);
+ if (rv)
+ goto out;
+ }
seq_printf(s, "Waiting Queue\n");
- list_for_each_entry(lkb, &res->res_waitqueue, lkb_statequeue)
- print_format1_lock(s, lkb, res);
+ list_for_each_entry(lkb, &res->res_waitqueue, lkb_statequeue) {
+ rv = print_format1_lock(s, lkb, res);
+ if (rv)
+ goto out;
+ }
if (list_empty(&res->res_lookup))
goto out;
seq_printf(s, "Lookup Queue\n");
list_for_each_entry(lkb, &res->res_lookup, lkb_rsb_lookup) {
- seq_printf(s, "%08x %s", lkb->lkb_id,
- print_lockmode(lkb->lkb_rqmode));
+ rv = seq_printf(s, "%08x %s", lkb->lkb_id,
+ print_lockmode(lkb->lkb_rqmode));
if (lkb->lkb_wait_type)
seq_printf(s, " wait_type: %d", lkb->lkb_wait_type);
- seq_printf(s, "\n");
+ rv = seq_printf(s, "\n");
}
out:
unlock_rsb(res);
- return 0;
+ return rv;
}
-static void print_format2_lock(struct seq_file *s, struct dlm_lkb *lkb,
- struct dlm_rsb *r)
+static int print_format2_lock(struct seq_file *s, struct dlm_lkb *lkb,
+ struct dlm_rsb *r)
{
u64 xid = 0;
u64 us;
+ int rv;
if (lkb->lkb_flags & DLM_IFL_USER) {
if (lkb->lkb_ua)
@@ -177,69 +187,82 @@ static void print_format2_lock(struct seq_file *s, struct dlm_lkb *lkb,
/* id nodeid remid pid xid exflags flags sts grmode rqmode time_us
r_nodeid r_len r_name */
- seq_printf(s, "%x %d %x %u %llu %x %x %d %d %d %llu %u %d \"%s\"\n",
- lkb->lkb_id,
- lkb->lkb_nodeid,
- lkb->lkb_remid,
- lkb->lkb_ownpid,
- (unsigned long long)xid,
- lkb->lkb_exflags,
- lkb->lkb_flags,
- lkb->lkb_status,
- lkb->lkb_grmode,
- lkb->lkb_rqmode,
- (unsigned long long)us,
- r->res_nodeid,
- r->res_length,
- r->res_name);
+ rv = seq_printf(s, "%x %d %x %u %llu %x %x %d %d %d %llu %u %d \"%s\"\n",
+ lkb->lkb_id,
+ lkb->lkb_nodeid,
+ lkb->lkb_remid,
+ lkb->lkb_ownpid,
+ (unsigned long long)xid,
+ lkb->lkb_exflags,
+ lkb->lkb_flags,
+ lkb->lkb_status,
+ lkb->lkb_grmode,
+ lkb->lkb_rqmode,
+ (unsigned long long)us,
+ r->res_nodeid,
+ r->res_length,
+ r->res_name);
+ return rv;
}
static int print_format2(struct dlm_rsb *r, struct seq_file *s)
{
struct dlm_lkb *lkb;
+ int rv = 0;
lock_rsb(r);
- list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue)
- print_format2_lock(s, lkb, r);
-
- list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue)
- print_format2_lock(s, lkb, r);
+ list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue) {
+ rv = print_format2_lock(s, lkb, r);
+ if (rv)
+ goto out;
+ }
- list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue)
- print_format2_lock(s, lkb, r);
+ list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue) {
+ rv = print_format2_lock(s, lkb, r);
+ if (rv)
+ goto out;
+ }
+ list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue) {
+ rv = print_format2_lock(s, lkb, r);
+ if (rv)
+ goto out;
+ }
+ out:
unlock_rsb(r);
- return 0;
+ return rv;
}
-static void print_format3_lock(struct seq_file *s, struct dlm_lkb *lkb,
- int rsb_lookup)
+static int print_format3_lock(struct seq_file *s, struct dlm_lkb *lkb,
+ int rsb_lookup)
{
u64 xid = 0;
+ int rv;
if (lkb->lkb_flags & DLM_IFL_USER) {
if (lkb->lkb_ua)
xid = lkb->lkb_ua->xid;
}
- seq_printf(s, "lkb %x %d %x %u %llu %x %x %d %d %d %d %d %d %u %llu %llu\n",
- lkb->lkb_id,
- lkb->lkb_nodeid,
- lkb->lkb_remid,
- lkb->lkb_ownpid,
- (unsigned long long)xid,
- lkb->lkb_exflags,
- lkb->lkb_flags,
- lkb->lkb_status,
- lkb->lkb_grmode,
- lkb->lkb_rqmode,
- lkb->lkb_highbast,
- rsb_lookup,
- lkb->lkb_wait_type,
- lkb->lkb_lvbseq,
- (unsigned long long)ktime_to_ns(lkb->lkb_timestamp),
- (unsigned long long)ktime_to_ns(lkb->lkb_time_bast));
+ rv = seq_printf(s, "lkb %x %d %x %u %llu %x %x %d %d %d %d %d %d %u %llu %llu\n",
+ lkb->lkb_id,
+ lkb->lkb_nodeid,
+ lkb->lkb_remid,
+ lkb->lkb_ownpid,
+ (unsigned long long)xid,
+ lkb->lkb_exflags,
+ lkb->lkb_flags,
+ lkb->lkb_status,
+ lkb->lkb_grmode,
+ lkb->lkb_rqmode,
+ lkb->lkb_highbast,
+ rsb_lookup,
+ lkb->lkb_wait_type,
+ lkb->lkb_lvbseq,
+ (unsigned long long)ktime_to_ns(lkb->lkb_timestamp),
+ (unsigned long long)ktime_to_ns(lkb->lkb_time_bast));
+ return rv;
}
static int print_format3(struct dlm_rsb *r, struct seq_file *s)
@@ -247,18 +270,21 @@ static int print_format3(struct dlm_rsb *r, struct seq_file *s)
struct dlm_lkb *lkb;
int i, lvblen = r->res_ls->ls_lvblen;
int print_name = 1;
+ int rv;
lock_rsb(r);
- seq_printf(s, "rsb %p %d %x %lx %d %d %u %d ",
- r,
- r->res_nodeid,
- r->res_first_lkid,
- r->res_flags,
- !list_empty(&r->res_root_list),
- !list_empty(&r->res_recover_list),
- r->res_recover_locks_count,
- r->res_length);
+ rv = seq_printf(s, "rsb %p %d %x %lx %d %d %u %d ",
+ r,
+ r->res_nodeid,
+ r->res_first_lkid,
+ r->res_flags,
+ !list_empty(&r->res_root_list),
+ !list_empty(&r->res_recover_list),
+ r->res_recover_locks_count,
+ r->res_length);
+ if (rv)
+ goto out;
for (i = 0; i < r->res_length; i++) {
if (!isascii(r->res_name[i]) || !isprint(r->res_name[i]))
@@ -273,7 +299,9 @@ static int print_format3(struct dlm_rsb *r, struct seq_file *s)
else
seq_printf(s, " %02x", (unsigned char)r->res_name[i]);
}
- seq_printf(s, "\n");
+ rv = seq_printf(s, "\n");
+ if (rv)
+ goto out;
if (!r->res_lvbptr)
goto do_locks;
@@ -282,344 +310,294 @@ static int print_format3(struct dlm_rsb *r, struct seq_file *s)
for (i = 0; i < lvblen; i++)
seq_printf(s, " %02x", (unsigned char)r->res_lvbptr[i]);
- seq_printf(s, "\n");
+ rv = seq_printf(s, "\n");
+ if (rv)
+ goto out;
do_locks:
- list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue)
- print_format3_lock(s, lkb, 0);
-
- list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue)
- print_format3_lock(s, lkb, 0);
-
- list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue)
- print_format3_lock(s, lkb, 0);
-
- list_for_each_entry(lkb, &r->res_lookup, lkb_rsb_lookup)
- print_format3_lock(s, lkb, 1);
-
- unlock_rsb(r);
- return 0;
-}
-
-static int rsb_iter_next(struct rsb_iter *ri)
-{
- struct dlm_ls *ls = ri->ls;
- int i;
-
- if (!ri->next) {
- top:
- /* Find the next non-empty hash bucket */
- for (i = ri->entry; i < ls->ls_rsbtbl_size; i++) {
- read_lock(&ls->ls_rsbtbl[i].lock);
- if (!list_empty(&ls->ls_rsbtbl[i].list)) {
- ri->next = ls->ls_rsbtbl[i].list.next;
- ri->rsb = list_entry(ri->next, struct dlm_rsb,
- res_hashchain);
- dlm_hold_rsb(ri->rsb);
- read_unlock(&ls->ls_rsbtbl[i].lock);
- break;
- }
- read_unlock(&ls->ls_rsbtbl[i].lock);
- }
- ri->entry = i;
-
- if (ri->entry >= ls->ls_rsbtbl_size)
- return 1;
- } else {
- struct dlm_rsb *old = ri->rsb;
- i = ri->entry;
- read_lock(&ls->ls_rsbtbl[i].lock);
- ri->next = ri->next->next;
- if (ri->next->next == ls->ls_rsbtbl[i].list.next) {
- /* End of list - move to next bucket */
- ri->next = NULL;
- ri->entry++;
- read_unlock(&ls->ls_rsbtbl[i].lock);
- dlm_put_rsb(old);
- goto top;
- }
- ri->rsb = list_entry(ri->next, struct dlm_rsb, res_hashchain);
- dlm_hold_rsb(ri->rsb);
- read_unlock(&ls->ls_rsbtbl[i].lock);
- dlm_put_rsb(old);
+ list_for_each_entry(lkb, &r->res_grantqueue, lkb_statequeue) {
+ rv = print_format3_lock(s, lkb, 0);
+ if (rv)
+ goto out;
}
- return 0;
-}
-
-static void rsb_iter_free(struct rsb_iter *ri)
-{
- kfree(ri);
-}
-
-static struct rsb_iter *rsb_iter_init(struct dlm_ls *ls)
-{
- struct rsb_iter *ri;
-
- ri = kzalloc(sizeof *ri, GFP_KERNEL);
- if (!ri)
- return NULL;
-
- ri->ls = ls;
- ri->entry = 0;
- ri->next = NULL;
- ri->format = 1;
-
- if (rsb_iter_next(ri)) {
- rsb_iter_free(ri);
- return NULL;
+ list_for_each_entry(lkb, &r->res_convertqueue, lkb_statequeue) {
+ rv = print_format3_lock(s, lkb, 0);
+ if (rv)
+ goto out;
}
- return ri;
-}
-
-static void *rsb_seq_start(struct seq_file *file, loff_t *pos)
-{
- struct rsb_iter *ri;
- loff_t n = *pos;
-
- ri = rsb_iter_init(file->private);
- if (!ri)
- return NULL;
-
- while (n--) {
- if (rsb_iter_next(ri)) {
- rsb_iter_free(ri);
- return NULL;
- }
+ list_for_each_entry(lkb, &r->res_waitqueue, lkb_statequeue) {
+ rv = print_format3_lock(s, lkb, 0);
+ if (rv)
+ goto out;
}
- return ri;
-}
-
-static void *rsb_seq_next(struct seq_file *file, void *iter_ptr, loff_t *pos)
-{
- struct rsb_iter *ri = iter_ptr;
-
- (*pos)++;
-
- if (rsb_iter_next(ri)) {
- rsb_iter_free(ri);
- return NULL;
+ list_for_each_entry(lkb, &r->res_lookup, lkb_rsb_lookup) {
+ rv = print_format3_lock(s, lkb, 1);
+ if (rv)
+ goto out;
}
-
- return ri;
+ out:
+ unlock_rsb(r);
+ return rv;
}
-static void rsb_seq_stop(struct seq_file *file, void *iter_ptr)
-{
- /* nothing for now */
-}
+struct rsbtbl_iter {
+ struct dlm_rsb *rsb;
+ unsigned bucket;
+ int format;
+ int header;
+};
-static int rsb_seq_show(struct seq_file *file, void *iter_ptr)
+/* seq_printf returns -1 if the buffer is full, and 0 otherwise.
+ If the buffer is full, seq_printf can be called again, but it
+ does nothing and just returns -1. So, the these printing routines
+ periodically check the return value to avoid wasting too much time
+ trying to print to a full buffer. */
+
+static int table_seq_show(struct seq_file *seq, void *iter_ptr)
{
- struct rsb_iter *ri = iter_ptr;
+ struct rsbtbl_iter *ri = iter_ptr;
+ int rv = 0;
switch (ri->format) {
case 1:
- print_format1(ri->rsb, file);
+ rv = print_format1(ri->rsb, seq);
break;
case 2:
if (ri->header) {
- seq_printf(file, "id nodeid remid pid xid exflags "
- "flags sts grmode rqmode time_ms "
- "r_nodeid r_len r_name\n");
+ seq_printf(seq, "id nodeid remid pid xid exflags "
+ "flags sts grmode rqmode time_ms "
+ "r_nodeid r_len r_name\n");
ri->header = 0;
}
- print_format2(ri->rsb, file);
+ rv = print_format2(ri->rsb, seq);
break;
case 3:
if (ri->header) {
- seq_printf(file, "version rsb 1.1 lvb 1.1 lkb 1.1\n");
+ seq_printf(seq, "version rsb 1.1 lvb 1.1 lkb 1.1\n");
ri->header = 0;
}
- print_format3(ri->rsb, file);
+ rv = print_format3(ri->rsb, seq);
break;
}
- return 0;
+ return rv;
}
-static struct seq_operations rsb_seq_ops = {
- .start = rsb_seq_start,
- .next = rsb_seq_next,
- .stop = rsb_seq_stop,
- .show = rsb_seq_show,
-};
+static struct seq_operations format1_seq_ops;
+static struct seq_operations format2_seq_ops;
+static struct seq_operations format3_seq_ops;
-static int rsb_open(struct inode *inode, struct file *file)
+static void *table_seq_start(struct seq_file *seq, loff_t *pos)
{
- struct seq_file *seq;
- int ret;
-
- ret = seq_open(file, &rsb_seq_ops);
- if (ret)
- return ret;
-
- seq = file->private_data;
- seq->private = inode->i_private;
-
- return 0;
-}
-
-static const struct file_operations rsb_fops = {
- .owner = THIS_MODULE,
- .open = rsb_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release
-};
+ struct dlm_ls *ls = seq->private;
+ struct rsbtbl_iter *ri;
+ struct dlm_rsb *r;
+ loff_t n = *pos;
+ unsigned bucket, entry;
-/*
- * Dump state in compact per-lock listing
- */
+ bucket = n >> 32;
+ entry = n & ((1LL << 32) - 1);
-static struct rsb_iter *locks_iter_init(struct dlm_ls *ls, loff_t *pos)
-{
- struct rsb_iter *ri;
+ if (bucket >= ls->ls_rsbtbl_size)
+ return NULL;
- ri = kzalloc(sizeof *ri, GFP_KERNEL);
+ ri = kzalloc(sizeof(struct rsbtbl_iter), GFP_KERNEL);
if (!ri)
return NULL;
-
- ri->ls = ls;
- ri->entry = 0;
- ri->next = NULL;
- ri->format = 2;
-
- if (*pos == 0)
+ if (n == 0)
ri->header = 1;
-
- if (rsb_iter_next(ri)) {
- rsb_iter_free(ri);
- return NULL;
+ if (seq->op == &format1_seq_ops)
+ ri->format = 1;
+ if (seq->op == &format2_seq_ops)
+ ri->format = 2;
+ if (seq->op == &format3_seq_ops)
+ ri->format = 3;
+
+ spin_lock(&ls->ls_rsbtbl[bucket].lock);
+ if (!list_empty(&ls->ls_rsbtbl[bucket].list)) {
+ list_for_each_entry(r, &ls->ls_rsbtbl[bucket].list,
+ res_hashchain) {
+ if (!entry--) {
+ dlm_hold_rsb(r);
+ ri->rsb = r;
+ ri->bucket = bucket;
+ spin_unlock(&ls->ls_rsbtbl[bucket].lock);
+ return ri;
+ }
+ }
}
+ spin_unlock(&ls->ls_rsbtbl[bucket].lock);
- return ri;
-}
+ /*
+ * move to the first rsb in the next non-empty bucket
+ */
-static void *locks_seq_start(struct seq_file *file, loff_t *pos)
-{
- struct rsb_iter *ri;
- loff_t n = *pos;
+ /* zero the entry */
+ n &= ~((1LL << 32) - 1);
- ri = locks_iter_init(file->private, pos);
- if (!ri)
- return NULL;
+ while (1) {
+ bucket++;
+ n += 1LL << 32;
- while (n--) {
- if (rsb_iter_next(ri)) {
- rsb_iter_free(ri);
+ if (bucket >= ls->ls_rsbtbl_size) {
+ kfree(ri);
return NULL;
}
- }
- return ri;
+ spin_lock(&ls->ls_rsbtbl[bucket].lock);
+ if (!list_empty(&ls->ls_rsbtbl[bucket].list)) {
+ r = list_first_entry(&ls->ls_rsbtbl[bucket].list,
+ struct dlm_rsb, res_hashchain);
+ dlm_hold_rsb(r);
+ ri->rsb = r;
+ ri->bucket = bucket;
+ spin_unlock(&ls->ls_rsbtbl[bucket].lock);
+ *pos = n;
+ return ri;
+ }
+ spin_unlock(&ls->ls_rsbtbl[bucket].lock);
+ }
}
-static struct seq_operations locks_seq_ops = {
- .start = locks_seq_start,
- .next = rsb_seq_next,
- .stop = rsb_seq_stop,
- .show = rsb_seq_show,
-};
-
-static int locks_open(struct inode *inode, struct file *file)
+static void *table_seq_next(struct seq_file *seq, void *iter_ptr, loff_t *pos)
{
- struct seq_file *seq;
- int ret;
-
- ret = seq_open(file, &locks_seq_ops);
- if (ret)
- return ret;
-
- seq = file->private_data;
- seq->private = inode->i_private;
-
- return 0;
-}
-
-static const struct file_operations locks_fops = {
- .owner = THIS_MODULE,
- .open = locks_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = seq_release
-};
-
-/*
- * Dump all rsb/lvb/lkb state in compact listing, more complete than _locks
- * This can replace both formats 1 and 2 eventually.
- */
+ struct dlm_ls *ls = seq->private;
+ struct rsbtbl_iter *ri = iter_ptr;
+ struct list_head *next;
+ struct dlm_rsb *r, *rp;
+ loff_t n = *pos;
+ unsigned bucket;
+
+ bucket = n >> 32;
+
+ /*
+ * move to the next rsb in the same bucket
+ */
+
+ spin_lock(&ls->ls_rsbtbl[bucket].lock);
+ rp = ri->rsb;
+ next = rp->res_hashchain.next;
+
+ if (next != &ls->ls_rsbtbl[bucket].list) {
+ r = list_entry(next, struct dlm_rsb, res_hashchain);
+ dlm_hold_rsb(r);
+ ri->rsb = r;
+ spin_unlock(&ls->ls_rsbtbl[bucket].lock);
+ dlm_put_rsb(rp);
+ ++*pos;
+ return ri;
+ }
+ spin_unlock(&ls->ls_rsbtbl[bucket].lock);
+ dlm_put_rsb(rp);
-static struct rsb_iter *all_iter_init(struct dlm_ls *ls, loff_t *pos)
-{
- struct rsb_iter *ri;
+ /*
+ * move to the first rsb in the next non-empty bucket
+ */
- ri = kzalloc(sizeof *ri, GFP_KERNEL);
- if (!ri)
- return NULL;
+ /* zero the entry */
+ n &= ~((1LL << 32) - 1);
- ri->ls = ls;
- ri->entry = 0;
- ri->next = NULL;
- ri->format = 3;
+ while (1) {
+ bucket++;
+ n += 1LL << 32;
- if (*pos == 0)
- ri->header = 1;
+ if (bucket >= ls->ls_rsbtbl_size) {
+ kfree(ri);
+ return NULL;
+ }
- if (rsb_iter_next(ri)) {
- rsb_iter_free(ri);
- return NULL;
+ spin_lock(&ls->ls_rsbtbl[bucket].lock);
+ if (!list_empty(&ls->ls_rsbtbl[bucket].list)) {
+ r = list_first_entry(&ls->ls_rsbtbl[bucket].list,
+ struct dlm_rsb, res_hashchain);
+ dlm_hold_rsb(r);
+ ri->rsb = r;
+ ri->bucket = bucket;
+ spin_unlock(&ls->ls_rsbtbl[bucket].lock);
+ *pos = n;
+ return ri;
+ }
+ spin_unlock(&ls->ls_rsbtbl[bucket].lock);
}
-
- return ri;
}
-static void *all_seq_start(struct seq_file *file, loff_t *pos)
+static void table_seq_stop(struct seq_file *seq, void *iter_ptr)
{
- struct rsb_iter *ri;
- loff_t n = *pos;
-
- ri = all_iter_init(file->private, pos);
- if (!ri)
- return NULL;
+ struct rsbtbl_iter *ri = iter_ptr;
- while (n--) {
- if (rsb_iter_next(ri)) {
- rsb_iter_free(ri);
- return NULL;
- }
+ if (ri) {
+ dlm_put_rsb(ri->rsb);
+ kfree(ri);
}
-
- return ri;
}
-static struct seq_operations all_seq_ops = {
- .start = all_seq_start,
- .next = rsb_seq_next,
- .stop = rsb_seq_stop,
- .show = rsb_seq_show,
+static struct seq_operations format1_seq_ops = {
+ .start = table_seq_start,
+ .next = table_seq_next,
+ .stop = table_seq_stop,
+ .show = table_seq_show,
};
-static int all_open(struct inode *inode, struct file *file)
+static struct seq_operations format2_seq_ops = {
+ .start = table_seq_start,
+ .next = table_seq_next,
+ .stop = table_seq_stop,
+ .show = table_seq_show,
+};
+
+static struct seq_operations format3_seq_ops = {
+ .start = table_seq_start,
+ .next = table_seq_next,
+ .stop = table_seq_stop,
+ .show = table_seq_show,
+};
+
+static const struct file_operations format1_fops;
+static const struct file_operations format2_fops;
+static const struct file_operations format3_fops;
+
+static int table_open(struct inode *inode, struct file *file)
{
struct seq_file *seq;
- int ret;
+ int ret = -1;
+
+ if (file->f_op == &format1_fops)
+ ret = seq_open(file, &format1_seq_ops);
+ else if (file->f_op == &format2_fops)
+ ret = seq_open(file, &format2_seq_ops);
+ else if (file->f_op == &format3_fops)
+ ret = seq_open(file, &format3_seq_ops);
- ret = seq_open(file, &all_seq_ops);
if (ret)
return ret;
seq = file->private_data;
- seq->private = inode->i_private;
-
+ seq->private = inode->i_private; /* the dlm_ls */
return 0;
}
-static const struct file_operations all_fops = {
+static const struct file_operations format1_fops = {
+ .owner = THIS_MODULE,
+ .open = table_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release
+};
+
+static const struct file_operations format2_fops = {
+ .owner = THIS_MODULE,
+ .open = table_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = seq_release
+};
+
+static const struct file_operations format3_fops = {
.owner = THIS_MODULE,
- .open = all_open,
+ .open = table_open,
.read = seq_read,
.llseek = seq_lseek,
.release = seq_release
@@ -689,7 +667,7 @@ int dlm_create_debug_file(struct dlm_ls *ls)
S_IFREG | S_IRUGO,
dlm_root,
ls,
- &rsb_fops);
+ &format1_fops);
if (!ls->ls_debug_rsb_dentry)
goto fail;
@@ -702,7 +680,7 @@ int dlm_create_debug_file(struct dlm_ls *ls)
S_IFREG | S_IRUGO,
dlm_root,
ls,
- &locks_fops);
+ &format2_fops);
if (!ls->ls_debug_locks_dentry)
goto fail;
@@ -715,7 +693,7 @@ int dlm_create_debug_file(struct dlm_ls *ls)
S_IFREG | S_IRUGO,
dlm_root,
ls,
- &all_fops);
+ &format3_fops);
if (!ls->ls_debug_all_dentry)
goto fail;
diff --git a/fs/dlm/dlm_internal.h b/fs/dlm/dlm_internal.h
index ef2f1e3..076e86f 100644
--- a/fs/dlm/dlm_internal.h
+++ b/fs/dlm/dlm_internal.h
@@ -105,7 +105,7 @@ struct dlm_dirtable {
struct dlm_rsbtable {
struct list_head list;
struct list_head toss;
- rwlock_t lock;
+ spinlock_t lock;
};
struct dlm_lkbtable {
diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index 6cfe65b..01e7d39 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -412,9 +412,9 @@ static int search_rsb(struct dlm_ls *ls, char *name, int len, int b,
unsigned int flags, struct dlm_rsb **r_ret)
{
int error;
- write_lock(&ls->ls_rsbtbl[b].lock);
+ spin_lock(&ls->ls_rsbtbl[b].lock);
error = _search_rsb(ls, name, len, b, flags, r_ret);
- write_unlock(&ls->ls_rsbtbl[b].lock);
+ spin_unlock(&ls->ls_rsbtbl[b].lock);
return error;
}
@@ -478,16 +478,16 @@ static int find_rsb(struct dlm_ls *ls, char *name, int namelen,
r->res_nodeid = nodeid;
}
- write_lock(&ls->ls_rsbtbl[bucket].lock);
+ spin_lock(&ls->ls_rsbtbl[bucket].lock);
error = _search_rsb(ls, name, namelen, bucket, 0, &tmp);
if (!error) {
- write_unlock(&ls->ls_rsbtbl[bucket].lock);
+ spin_unlock(&ls->ls_rsbtbl[bucket].lock);
dlm_free_rsb(r);
r = tmp;
goto out;
}
list_add(&r->res_hashchain, &ls->ls_rsbtbl[bucket].list);
- write_unlock(&ls->ls_rsbtbl[bucket].lock);
+ spin_unlock(&ls->ls_rsbtbl[bucket].lock);
error = 0;
out:
*r_ret = r;
@@ -530,9 +530,9 @@ static void put_rsb(struct dlm_rsb *r)
struct dlm_ls *ls = r->res_ls;
uint32_t bucket = r->res_bucket;
- write_lock(&ls->ls_rsbtbl[bucket].lock);
+ spin_lock(&ls->ls_rsbtbl[bucket].lock);
kref_put(&r->res_ref, toss_rsb);
- write_unlock(&ls->ls_rsbtbl[bucket].lock);
+ spin_unlock(&ls->ls_rsbtbl[bucket].lock);
}
void dlm_put_rsb(struct dlm_rsb *r)
@@ -967,7 +967,7 @@ static int shrink_bucket(struct dlm_ls *ls, int b)
for (;;) {
found = 0;
- write_lock(&ls->ls_rsbtbl[b].lock);
+ spin_lock(&ls->ls_rsbtbl[b].lock);
list_for_each_entry_reverse(r, &ls->ls_rsbtbl[b].toss,
res_hashchain) {
if (!time_after_eq(jiffies, r->res_toss_time +
@@ -978,20 +978,20 @@ static int shrink_bucket(struct dlm_ls *ls, int b)
}
if (!found) {
- write_unlock(&ls->ls_rsbtbl[b].lock);
+ spin_unlock(&ls->ls_rsbtbl[b].lock);
break;
}
if (kref_put(&r->res_ref, kill_rsb)) {
list_del(&r->res_hashchain);
- write_unlock(&ls->ls_rsbtbl[b].lock);
+ spin_unlock(&ls->ls_rsbtbl[b].lock);
if (is_master(r))
dir_remove(r);
dlm_free_rsb(r);
count++;
} else {
- write_unlock(&ls->ls_rsbtbl[b].lock);
+ spin_unlock(&ls->ls_rsbtbl[b].lock);
log_error(ls, "tossed rsb in use %s", r->res_name);
}
}
@@ -4224,7 +4224,7 @@ static struct dlm_rsb *find_purged_rsb(struct dlm_ls *ls, int bucket)
{
struct dlm_rsb *r, *r_ret = NULL;
- read_lock(&ls->ls_rsbtbl[bucket].lock);
+ spin_lock(&ls->ls_rsbtbl[bucket].lock);
list_for_each_entry(r, &ls->ls_rsbtbl[bucket].list, res_hashchain) {
if (!rsb_flag(r, RSB_LOCKS_PURGED))
continue;
@@ -4233,7 +4233,7 @@ static struct dlm_rsb *find_purged_rsb(struct dlm_ls *ls, int bucket)
r_ret = r;
break;
}
- read_unlock(&ls->ls_rsbtbl[bucket].lock);
+ spin_unlock(&ls->ls_rsbtbl[bucket].lock);
return r_ret;
}
diff --git a/fs/dlm/lockspace.c b/fs/dlm/lockspace.c
index 8d86b79..aa32e5f 100644
--- a/fs/dlm/lockspace.c
+++ b/fs/dlm/lockspace.c
@@ -464,7 +464,7 @@ static int new_lockspace(char *name, int namelen, void **lockspace,
for (i = 0; i < size; i++) {
INIT_LIST_HEAD(&ls->ls_rsbtbl[i].list);
INIT_LIST_HEAD(&ls->ls_rsbtbl[i].toss);
- rwlock_init(&ls->ls_rsbtbl[i].lock);
+ spin_lock_init(&ls->ls_rsbtbl[i].lock);
}
size = dlm_config.ci_lkbtbl_size;
diff --git a/fs/dlm/recover.c b/fs/dlm/recover.c
index 80aba5b..eda43f3 100644
--- a/fs/dlm/recover.c
+++ b/fs/dlm/recover.c
@@ -726,7 +726,7 @@ int dlm_create_root_list(struct dlm_ls *ls)
}
for (i = 0; i < ls->ls_rsbtbl_size; i++) {
- read_lock(&ls->ls_rsbtbl[i].lock);
+ spin_lock(&ls->ls_rsbtbl[i].lock);
list_for_each_entry(r, &ls->ls_rsbtbl[i].list, res_hashchain) {
list_add(&r->res_root_list, &ls->ls_root_list);
dlm_hold_rsb(r);
@@ -737,7 +737,7 @@ int dlm_create_root_list(struct dlm_ls *ls)
but no other recovery steps should do anything with them. */
if (dlm_no_directory(ls)) {
- read_unlock(&ls->ls_rsbtbl[i].lock);
+ spin_unlock(&ls->ls_rsbtbl[i].lock);
continue;
}
@@ -745,7 +745,7 @@ int dlm_create_root_list(struct dlm_ls *ls)
list_add(&r->res_root_list, &ls->ls_root_list);
dlm_hold_rsb(r);
}
- read_unlock(&ls->ls_rsbtbl[i].lock);
+ spin_unlock(&ls->ls_rsbtbl[i].lock);
}
out:
up_write(&ls->ls_root_sem);
@@ -775,7 +775,7 @@ void dlm_clear_toss_list(struct dlm_ls *ls)
int i;
for (i = 0; i < ls->ls_rsbtbl_size; i++) {
- write_lock(&ls->ls_rsbtbl[i].lock);
+ spin_lock(&ls->ls_rsbtbl[i].lock);
list_for_each_entry_safe(r, safe, &ls->ls_rsbtbl[i].toss,
res_hashchain) {
if (dlm_no_directory(ls) || !is_master(r)) {
@@ -783,7 +783,7 @@ void dlm_clear_toss_list(struct dlm_ls *ls)
dlm_free_rsb(r);
}
}
- write_unlock(&ls->ls_rsbtbl[i].lock);
+ spin_unlock(&ls->ls_rsbtbl[i].lock);
}
}
diff --git a/fs/select.c b/fs/select.c
index 08b91be..b0cf1f0 100644
--- a/fs/select.c
+++ b/fs/select.c
@@ -610,7 +610,7 @@ asmlinkage long sys_pselect7(int n, fd_set __user *inp, fd_set __user *outp,
sigprocmask(SIG_SETMASK, &ksigmask, &sigsaved);
}
- ret = core_sys_select(n, inp, outp, exp, &end_time);
+ ret = core_sys_select(n, inp, outp, exp, to);
ret = poll_select_copy_remaining(&end_time, tsp, 0, ret);
if (ret == -ERESTARTNOHAND) {
diff --git a/include/asm-generic/bitops/__ffs.h b/include/asm-generic/bitops/__ffs.h
index 9a3274a..937d7c4 100644
--- a/include/asm-generic/bitops/__ffs.h
+++ b/include/asm-generic/bitops/__ffs.h
@@ -9,7 +9,7 @@
*
* Undefined if no bit exists, so code should check against 0 first.
*/
-static inline unsigned long __ffs(unsigned long word)
+static __always_inline unsigned long __ffs(unsigned long word)
{
int num = 0;
diff --git a/include/asm-generic/bitops/__fls.h b/include/asm-generic/bitops/__fls.h
index be24465..a60a7cc 100644
--- a/include/asm-generic/bitops/__fls.h
+++ b/include/asm-generic/bitops/__fls.h
@@ -9,7 +9,7 @@
*
* Undefined if no set bit exists, so code should check against 0 first.
*/
-static inline unsigned long __fls(unsigned long word)
+static __always_inline unsigned long __fls(unsigned long word)
{
int num = BITS_PER_LONG - 1;
diff --git a/include/asm-generic/bitops/fls.h b/include/asm-generic/bitops/fls.h
index 850859b..0576d1f 100644
--- a/include/asm-generic/bitops/fls.h
+++ b/include/asm-generic/bitops/fls.h
@@ -9,7 +9,7 @@
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
*/
-static inline int fls(int x)
+static __always_inline int fls(int x)
{
int r = 32;
diff --git a/include/asm-generic/bitops/fls64.h b/include/asm-generic/bitops/fls64.h
index 86d403f..b097cf8 100644
--- a/include/asm-generic/bitops/fls64.h
+++ b/include/asm-generic/bitops/fls64.h
@@ -15,7 +15,7 @@
* at position 64.
*/
#if BITS_PER_LONG == 32
-static inline int fls64(__u64 x)
+static __always_inline int fls64(__u64 x)
{
__u32 h = x >> 32;
if (h)
@@ -23,7 +23,7 @@ static inline int fls64(__u64 x)
return fls(x);
}
#elif BITS_PER_LONG == 64
-static inline int fls64(__u64 x)
+static __always_inline int fls64(__u64 x)
{
if (x == 0)
return 0;
diff --git a/include/asm-generic/percpu.h b/include/asm-generic/percpu.h
index b0e63c6..00f45ff 100644
--- a/include/asm-generic/percpu.h
+++ b/include/asm-generic/percpu.h
@@ -80,4 +80,56 @@ extern void setup_per_cpu_areas(void);
#define DECLARE_PER_CPU(type, name) extern PER_CPU_ATTRIBUTES \
__typeof__(type) per_cpu_var(name)
+/*
+ * Optional methods for optimized non-lvalue per-cpu variable access.
+ *
+ * @var can be a percpu variable or a field of it and its size should
+ * equal char, int or long. percpu_read() evaluates to a lvalue and
+ * all others to void.
+ *
+ * These operations are guaranteed to be atomic w.r.t. preemption.
+ * The generic versions use plain get/put_cpu_var(). Archs are
+ * encouraged to implement single-instruction alternatives which don't
+ * require preemption protection.
+ */
+#ifndef percpu_read
+# define percpu_read(var) \
+ ({ \
+ typeof(per_cpu_var(var)) __tmp_var__; \
+ __tmp_var__ = get_cpu_var(var); \
+ put_cpu_var(var); \
+ __tmp_var__; \
+ })
+#endif
+
+#define __percpu_generic_to_op(var, val, op) \
+do { \
+ get_cpu_var(var) op val; \
+ put_cpu_var(var); \
+} while (0)
+
+#ifndef percpu_write
+# define percpu_write(var, val) __percpu_generic_to_op(var, (val), =)
+#endif
+
+#ifndef percpu_add
+# define percpu_add(var, val) __percpu_generic_to_op(var, (val), +=)
+#endif
+
+#ifndef percpu_sub
+# define percpu_sub(var, val) __percpu_generic_to_op(var, (val), -=)
+#endif
+
+#ifndef percpu_and
+# define percpu_and(var, val) __percpu_generic_to_op(var, (val), &=)
+#endif
+
+#ifndef percpu_or
+# define percpu_or(var, val) __percpu_generic_to_op(var, (val), |=)
+#endif
+
+#ifndef percpu_xor
+# define percpu_xor(var, val) __percpu_generic_to_op(var, (val), ^=)
+#endif
+
#endif /* _ASM_GENERIC_PERCPU_H_ */
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 72ebe91..8e6d0ca 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -301,7 +301,7 @@ static inline void ptep_modify_prot_commit(struct mm_struct *mm,
* track_pfn_vma_new is called when a _new_ pfn mapping is being established
* for physical range indicated by pfn and size.
*/
-static inline int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t prot,
+static inline int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t *prot,
unsigned long pfn, unsigned long size)
{
return 0;
@@ -332,7 +332,7 @@ static inline void untrack_pfn_vma(struct vm_area_struct *vma,
{
}
#else
-extern int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t prot,
+extern int track_pfn_vma_new(struct vm_area_struct *vma, pgprot_t *prot,
unsigned long pfn, unsigned long size);
extern int track_pfn_vma_copy(struct vm_area_struct *vma);
extern void untrack_pfn_vma(struct vm_area_struct *vma, unsigned long pfn,
diff --git a/include/asm-generic/sections.h b/include/asm-generic/sections.h
index 79a7ff9..4ce48e8 100644
--- a/include/asm-generic/sections.h
+++ b/include/asm-generic/sections.h
@@ -9,7 +9,7 @@ extern char __bss_start[], __bss_stop[];
extern char __init_begin[], __init_end[];
extern char _sinittext[], _einittext[];
extern char _end[];
-extern char __per_cpu_start[], __per_cpu_end[];
+extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[];
extern char __kprobes_text_start[], __kprobes_text_end[];
extern char __initdata_begin[], __initdata_end[];
extern char __start_rodata[], __end_rodata[];
diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h
index c61fab1..aa6b9b1 100644
--- a/include/asm-generic/vmlinux.lds.h
+++ b/include/asm-generic/vmlinux.lds.h
@@ -430,12 +430,75 @@
*(.initcall7.init) \
*(.initcall7s.init)
-#define PERCPU(align) \
- . = ALIGN(align); \
- VMLINUX_SYMBOL(__per_cpu_start) = .; \
- .data.percpu : AT(ADDR(.data.percpu) - LOAD_OFFSET) { \
+#define PERCPU_PROLOG(vaddr) \
+ VMLINUX_SYMBOL(__per_cpu_load) = .; \
+ .data.percpu vaddr : AT(VMLINUX_SYMBOL(__per_cpu_load) \
+ - LOAD_OFFSET) { \
+ VMLINUX_SYMBOL(__per_cpu_start) = .;
+
+#define PERCPU_EPILOG(phdr) \
+ VMLINUX_SYMBOL(__per_cpu_end) = .; \
+ } phdr \
+ . = VMLINUX_SYMBOL(__per_cpu_load) + SIZEOF(.data.percpu);
+
+/**
+ * PERCPU_VADDR_PREALLOC - define output section for percpu area with prealloc
+ * @vaddr: explicit base address (optional)
+ * @phdr: destination PHDR (optional)
+ * @prealloc: the size of prealloc area
+ *
+ * Macro which expands to output section for percpu area. If @vaddr
+ * is not blank, it specifies explicit base address and all percpu
+ * symbols will be offset from the given address. If blank, @vaddr
+ * always equals @laddr + LOAD_OFFSET.
+ *
+ * @phdr defines the output PHDR to use if not blank. Be warned that
+ * output PHDR is sticky. If @phdr is specified, the next output
+ * section in the linker script will go there too. @phdr should have
+ * a leading colon.
+ *
+ * If @prealloc is non-zero, the specified number of bytes will be
+ * reserved at the start of percpu area. As the prealloc area is
+ * likely to break alignment, this macro puts areas in increasing
+ * alignment order.
+ *
+ * This macro defines three symbols, __per_cpu_load, __per_cpu_start
+ * and __per_cpu_end. The first one is the vaddr of loaded percpu
+ * init data. __per_cpu_start equals @vaddr and __per_cpu_end is the
+ * end offset.
+ */
+#define PERCPU_VADDR_PREALLOC(vaddr, segment, prealloc) \
+ PERCPU_PROLOG(vaddr) \
+ . += prealloc; \
+ *(.data.percpu) \
+ *(.data.percpu.shared_aligned) \
+ *(.data.percpu.page_aligned) \
+ PERCPU_EPILOG(segment)
+
+/**
+ * PERCPU_VADDR - define output section for percpu area
+ * @vaddr: explicit base address (optional)
+ * @phdr: destination PHDR (optional)
+ *
+ * Macro which expands to output section for percpu area. Mostly
+ * identical to PERCPU_VADDR_PREALLOC(@vaddr, @phdr, 0) other than
+ * using slighly different layout.
+ */
+#define PERCPU_VADDR(vaddr, phdr) \
+ PERCPU_PROLOG(vaddr) \
*(.data.percpu.page_aligned) \
*(.data.percpu) \
*(.data.percpu.shared_aligned) \
- } \
- VMLINUX_SYMBOL(__per_cpu_end) = .;
+ PERCPU_EPILOG(phdr)
+
+/**
+ * PERCPU - define output section for percpu area, simple version
+ * @align: required alignment
+ *
+ * Align to @align and outputs output section for percpu area. This
+ * macro doesn't maniuplate @vaddr or @phdr and __per_cpu_load and
+ * __per_cpu_start will be identical.
+ */
+#define PERCPU(align) \
+ . = ALIGN(align); \
+ PERCPU_VADDR( , )
diff --git a/include/asm-m68k/unistd.h b/include/asm-m68k/unistd.h
index 965abb8..3c19027 100644
--- a/include/asm-m68k/unistd.h
+++ b/include/asm-m68k/unistd.h
@@ -5,6 +5,7 @@
* This file contains the system call numbers.
*/
+#define __NR_restart_syscall 0
#define __NR_exit 1
#define __NR_fork 2
#define __NR_read 3
@@ -359,9 +360,6 @@
#define __ARCH_WANT_SYS_SIGPROCMASK
#define __ARCH_WANT_SYS_RT_SIGACTION
-/* whitelist for checksyscalls */
-#define __IGNORE_restart_syscall
-
/*
* "Conditional" syscalls
*
diff --git a/include/linux/dio.h b/include/linux/dio.h
index 1e65ebc..b2dd31c 100644
--- a/include/linux/dio.h
+++ b/include/linux/dio.h
@@ -241,7 +241,7 @@ struct dio_driver {
extern int dio_find(int deviceid);
extern unsigned long dio_scodetophysaddr(int scode);
-extern void dio_create_sysfs_dev_files(struct dio_dev *);
+extern int dio_create_sysfs_dev_files(struct dio_dev *);
/* New-style probing */
extern int dio_register_driver(struct dio_driver *);
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 64dea2a..c73f1e2 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -270,8 +270,18 @@ struct dma_device {
/* --- public DMA engine API --- */
+#ifdef CONFIG_DMA_ENGINE
void dmaengine_get(void);
void dmaengine_put(void);
+#else
+static inline void dmaengine_get(void)
+{
+}
+static inline void dmaengine_put(void)
+{
+}
+#endif
+
dma_cookie_t dma_async_memcpy_buf_to_buf(struct dma_chan *chan,
void *dest, void *src, size_t len);
dma_cookie_t dma_async_memcpy_buf_to_pg(struct dma_chan *chan,
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 9127f6b..472f117 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -467,6 +467,7 @@ int show_interrupts(struct seq_file *p, void *v);
struct irq_desc;
extern int early_irq_init(void);
+extern int arch_probe_nr_irqs(void);
extern int arch_early_irq_init(void);
extern int arch_init_chip_data(struct irq_desc *desc, int cpu);
diff --git a/include/linux/irq.h b/include/linux/irq.h
index f899b50..27a6753 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -182,11 +182,11 @@ struct irq_desc {
unsigned int irqs_unhandled;
spinlock_t lock;
#ifdef CONFIG_SMP
- cpumask_t affinity;
+ cpumask_var_t affinity;
unsigned int cpu;
-#endif
#ifdef CONFIG_GENERIC_PENDING_IRQ
- cpumask_t pending_mask;
+ cpumask_var_t pending_mask;
+#endif
#endif
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *dir;
@@ -422,4 +422,84 @@ extern int set_irq_msi(unsigned int irq, struct msi_desc *entry);
#endif /* !CONFIG_S390 */
+#ifdef CONFIG_SMP
+/**
+ * init_alloc_desc_masks - allocate cpumasks for irq_desc
+ * @desc: pointer to irq_desc struct
+ * @cpu: cpu which will be handling the cpumasks
+ * @boot: true if need bootmem
+ *
+ * Allocates affinity and pending_mask cpumask if required.
+ * Returns true if successful (or not required).
+ * Side effect: affinity has all bits set, pending_mask has all bits clear.
+ */
+static inline bool init_alloc_desc_masks(struct irq_desc *desc, int cpu,
+ bool boot)
+{
+ int node;
+
+ if (boot) {
+ alloc_bootmem_cpumask_var(&desc->affinity);
+ cpumask_setall(desc->affinity);
+
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+ alloc_bootmem_cpumask_var(&desc->pending_mask);
+ cpumask_clear(desc->pending_mask);
+#endif
+ return true;
+ }
+
+ node = cpu_to_node(cpu);
+
+ if (!alloc_cpumask_var_node(&desc->affinity, GFP_ATOMIC, node))
+ return false;
+ cpumask_setall(desc->affinity);
+
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+ if (!alloc_cpumask_var_node(&desc->pending_mask, GFP_ATOMIC, node)) {
+ free_cpumask_var(desc->affinity);
+ return false;
+ }
+ cpumask_clear(desc->pending_mask);
+#endif
+ return true;
+}
+
+/**
+ * init_copy_desc_masks - copy cpumasks for irq_desc
+ * @old_desc: pointer to old irq_desc struct
+ * @new_desc: pointer to new irq_desc struct
+ *
+ * Insures affinity and pending_masks are copied to new irq_desc.
+ * If !CONFIG_CPUMASKS_OFFSTACK the cpumasks are embedded in the
+ * irq_desc struct so the copy is redundant.
+ */
+
+static inline void init_copy_desc_masks(struct irq_desc *old_desc,
+ struct irq_desc *new_desc)
+{
+#ifdef CONFIG_CPUMASKS_OFFSTACK
+ cpumask_copy(new_desc->affinity, old_desc->affinity);
+
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+ cpumask_copy(new_desc->pending_mask, old_desc->pending_mask);
+#endif
+#endif
+}
+
+#else /* !CONFIG_SMP */
+
+static inline bool init_alloc_desc_masks(struct irq_desc *desc, int cpu,
+ bool boot)
+{
+ return true;
+}
+
+static inline void init_copy_desc_masks(struct irq_desc *old_desc,
+ struct irq_desc *new_desc)
+{
+}
+
+#endif /* CONFIG_SMP */
+
#endif /* _LINUX_IRQ_H */
diff --git a/include/linux/irqnr.h b/include/linux/irqnr.h
index 86af92e..887477b 100644
--- a/include/linux/irqnr.h
+++ b/include/linux/irqnr.h
@@ -20,6 +20,7 @@
# define for_each_irq_desc_reverse(irq, desc) \
for (irq = nr_irqs - 1; irq >= 0; irq--)
+
#else /* CONFIG_GENERIC_HARDIRQS */
extern int nr_irqs;
diff --git a/include/linux/mISDNif.h b/include/linux/mISDNif.h
index 557477a..5da3d95 100644
--- a/include/linux/mISDNif.h
+++ b/include/linux/mISDNif.h
@@ -559,7 +559,10 @@ extern void mISDN_unregister_clock(struct mISDNclock *);
static inline struct mISDNdevice *dev_to_mISDN(struct device *dev)
{
- return dev_get_drvdata(dev);
+ if (dev)
+ return dev_get_drvdata(dev);
+ else
+ return NULL;
}
extern void set_channel_address(struct mISDNchannel *, u_int, u_int);
diff --git a/include/linux/mfd/pcf50633/adc.h b/include/linux/mfd/pcf50633/adc.h
new file mode 100644
index 0000000..56669b4
--- /dev/null
+++ b/include/linux/mfd/pcf50633/adc.h
@@ -0,0 +1,72 @@
+/*
+ * adc.h -- Driver for NXP PCF50633 ADC
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __LINUX_MFD_PCF50633_ADC_H
+#define __LINUX_MFD_PCF50633_ADC_H
+
+#include <linux/mfd/pcf50633/core.h>
+#include <linux/platform_device.h>
+
+/* ADC Registers */
+#define PCF50633_REG_ADCC3 0x52
+#define PCF50633_REG_ADCC2 0x53
+#define PCF50633_REG_ADCC1 0x54
+#define PCF50633_REG_ADCS1 0x55
+#define PCF50633_REG_ADCS2 0x56
+#define PCF50633_REG_ADCS3 0x57
+
+#define PCF50633_ADCC1_ADCSTART 0x01
+#define PCF50633_ADCC1_RES_10BIT 0x02
+#define PCF50633_ADCC1_AVERAGE_NO 0x00
+#define PCF50633_ADCC1_AVERAGE_4 0x04
+#define PCF50633_ADCC1_AVERAGE_8 0x08
+#define PCF50633_ADCC1_AVERAGE_16 0x0c
+#define PCF50633_ADCC1_MUX_BATSNS_RES 0x00
+#define PCF50633_ADCC1_MUX_BATSNS_SUBTR 0x10
+#define PCF50633_ADCC1_MUX_ADCIN2_RES 0x20
+#define PCF50633_ADCC1_MUX_ADCIN2_SUBTR 0x30
+#define PCF50633_ADCC1_MUX_BATTEMP 0x60
+#define PCF50633_ADCC1_MUX_ADCIN1 0x70
+#define PCF50633_ADCC1_AVERAGE_MASK 0x0c
+#define PCF50633_ADCC1_ADCMUX_MASK 0xf0
+
+#define PCF50633_ADCC2_RATIO_NONE 0x00
+#define PCF50633_ADCC2_RATIO_BATTEMP 0x01
+#define PCF50633_ADCC2_RATIO_ADCIN1 0x02
+#define PCF50633_ADCC2_RATIO_BOTH 0x03
+#define PCF50633_ADCC2_RATIOSETTL_100US 0x04
+
+#define PCF50633_ADCC3_ACCSW_EN 0x01
+#define PCF50633_ADCC3_NTCSW_EN 0x04
+#define PCF50633_ADCC3_RES_DIV_TWO 0x10
+#define PCF50633_ADCC3_RES_DIV_THREE 0x00
+
+#define PCF50633_ADCS3_REF_NTCSW 0x00
+#define PCF50633_ADCS3_REF_ACCSW 0x10
+#define PCF50633_ADCS3_REF_2V0 0x20
+#define PCF50633_ADCS3_REF_VISA 0x30
+#define PCF50633_ADCS3_REF_2V0_2 0x70
+#define PCF50633_ADCS3_ADCRDY 0x80
+
+#define PCF50633_ADCS3_ADCDAT1L_MASK 0x03
+#define PCF50633_ADCS3_ADCDAT2L_MASK 0x0c
+#define PCF50633_ADCS3_ADCDAT2L_SHIFT 2
+#define PCF50633_ASCS3_REF_MASK 0x70
+
+extern int
+pcf50633_adc_async_read(struct pcf50633 *pcf, int mux, int avg,
+ void (*callback)(struct pcf50633 *, void *, int),
+ void *callback_param);
+extern int
+pcf50633_adc_sync_read(struct pcf50633 *pcf, int mux, int avg);
+
+#endif /* __LINUX_PCF50633_ADC_H */
diff --git a/include/linux/mfd/pcf50633/core.h b/include/linux/mfd/pcf50633/core.h
new file mode 100644
index 0000000..4455b21
--- /dev/null
+++ b/include/linux/mfd/pcf50633/core.h
@@ -0,0 +1,218 @@
+/*
+ * core.h -- Core driver for NXP PCF50633
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __LINUX_MFD_PCF50633_CORE_H
+#define __LINUX_MFD_PCF50633_CORE_H
+
+#include <linux/i2c.h>
+#include <linux/workqueue.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/power_supply.h>
+
+struct pcf50633;
+
+#define PCF50633_NUM_REGULATORS 11
+
+struct pcf50633_platform_data {
+ struct regulator_init_data reg_init_data[PCF50633_NUM_REGULATORS];
+
+ char **batteries;
+ int num_batteries;
+
+ /* Callbacks */
+ void (*probe_done)(struct pcf50633 *);
+ void (*mbc_event_callback)(struct pcf50633 *, int);
+ void (*regulator_registered)(struct pcf50633 *, int);
+ void (*force_shutdown)(struct pcf50633 *);
+
+ u8 resumers[5];
+};
+
+struct pcf50633_subdev_pdata {
+ struct pcf50633 *pcf;
+};
+
+struct pcf50633_irq {
+ void (*handler) (int, void *);
+ void *data;
+};
+
+int pcf50633_register_irq(struct pcf50633 *pcf, int irq,
+ void (*handler) (int, void *), void *data);
+int pcf50633_free_irq(struct pcf50633 *pcf, int irq);
+
+int pcf50633_irq_mask(struct pcf50633 *pcf, int irq);
+int pcf50633_irq_unmask(struct pcf50633 *pcf, int irq);
+int pcf50633_irq_mask_get(struct pcf50633 *pcf, int irq);
+
+int pcf50633_read_block(struct pcf50633 *, u8 reg,
+ int nr_regs, u8 *data);
+int pcf50633_write_block(struct pcf50633 *pcf, u8 reg,
+ int nr_regs, u8 *data);
+u8 pcf50633_reg_read(struct pcf50633 *, u8 reg);
+int pcf50633_reg_write(struct pcf50633 *pcf, u8 reg, u8 val);
+
+int pcf50633_reg_set_bit_mask(struct pcf50633 *pcf, u8 reg, u8 mask, u8 val);
+int pcf50633_reg_clear_bits(struct pcf50633 *pcf, u8 reg, u8 bits);
+
+/* Interrupt registers */
+
+#define PCF50633_REG_INT1 0x02
+#define PCF50633_REG_INT2 0x03
+#define PCF50633_REG_INT3 0x04
+#define PCF50633_REG_INT4 0x05
+#define PCF50633_REG_INT5 0x06
+
+#define PCF50633_REG_INT1M 0x07
+#define PCF50633_REG_INT2M 0x08
+#define PCF50633_REG_INT3M 0x09
+#define PCF50633_REG_INT4M 0x0a
+#define PCF50633_REG_INT5M 0x0b
+
+enum {
+ /* Chip IRQs */
+ PCF50633_IRQ_ADPINS,
+ PCF50633_IRQ_ADPREM,
+ PCF50633_IRQ_USBINS,
+ PCF50633_IRQ_USBREM,
+ PCF50633_IRQ_RESERVED1,
+ PCF50633_IRQ_RESERVED2,
+ PCF50633_IRQ_ALARM,
+ PCF50633_IRQ_SECOND,
+ PCF50633_IRQ_ONKEYR,
+ PCF50633_IRQ_ONKEYF,
+ PCF50633_IRQ_EXTON1R,
+ PCF50633_IRQ_EXTON1F,
+ PCF50633_IRQ_EXTON2R,
+ PCF50633_IRQ_EXTON2F,
+ PCF50633_IRQ_EXTON3R,
+ PCF50633_IRQ_EXTON3F,
+ PCF50633_IRQ_BATFULL,
+ PCF50633_IRQ_CHGHALT,
+ PCF50633_IRQ_THLIMON,
+ PCF50633_IRQ_THLIMOFF,
+ PCF50633_IRQ_USBLIMON,
+ PCF50633_IRQ_USBLIMOFF,
+ PCF50633_IRQ_ADCRDY,
+ PCF50633_IRQ_ONKEY1S,
+ PCF50633_IRQ_LOWSYS,
+ PCF50633_IRQ_LOWBAT,
+ PCF50633_IRQ_HIGHTMP,
+ PCF50633_IRQ_AUTOPWRFAIL,
+ PCF50633_IRQ_DWN1PWRFAIL,
+ PCF50633_IRQ_DWN2PWRFAIL,
+ PCF50633_IRQ_LEDPWRFAIL,
+ PCF50633_IRQ_LEDOVP,
+ PCF50633_IRQ_LDO1PWRFAIL,
+ PCF50633_IRQ_LDO2PWRFAIL,
+ PCF50633_IRQ_LDO3PWRFAIL,
+ PCF50633_IRQ_LDO4PWRFAIL,
+ PCF50633_IRQ_LDO5PWRFAIL,
+ PCF50633_IRQ_LDO6PWRFAIL,
+ PCF50633_IRQ_HCLDOPWRFAIL,
+ PCF50633_IRQ_HCLDOOVL,
+
+ /* Always last */
+ PCF50633_NUM_IRQ,
+};
+
+struct pcf50633 {
+ struct device *dev;
+ struct i2c_client *i2c_client;
+
+ struct pcf50633_platform_data *pdata;
+ int irq;
+ struct pcf50633_irq irq_handler[PCF50633_NUM_IRQ];
+ struct work_struct irq_work;
+ struct mutex lock;
+
+ u8 mask_regs[5];
+
+ u8 suspend_irq_masks[5];
+ u8 resume_reason[5];
+ int is_suspended;
+
+ int onkey1s_held;
+
+ struct platform_device *rtc_pdev;
+ struct platform_device *mbc_pdev;
+ struct platform_device *adc_pdev;
+ struct platform_device *input_pdev;
+ struct platform_device *regulator_pdev[PCF50633_NUM_REGULATORS];
+};
+
+enum pcf50633_reg_int1 {
+ PCF50633_INT1_ADPINS = 0x01, /* Adapter inserted */
+ PCF50633_INT1_ADPREM = 0x02, /* Adapter removed */
+ PCF50633_INT1_USBINS = 0x04, /* USB inserted */
+ PCF50633_INT1_USBREM = 0x08, /* USB removed */
+ /* reserved */
+ PCF50633_INT1_ALARM = 0x40, /* RTC alarm time is reached */
+ PCF50633_INT1_SECOND = 0x80, /* RTC periodic second interrupt */
+};
+
+enum pcf50633_reg_int2 {
+ PCF50633_INT2_ONKEYR = 0x01, /* ONKEY rising edge */
+ PCF50633_INT2_ONKEYF = 0x02, /* ONKEY falling edge */
+ PCF50633_INT2_EXTON1R = 0x04, /* EXTON1 rising edge */
+ PCF50633_INT2_EXTON1F = 0x08, /* EXTON1 falling edge */
+ PCF50633_INT2_EXTON2R = 0x10, /* EXTON2 rising edge */
+ PCF50633_INT2_EXTON2F = 0x20, /* EXTON2 falling edge */
+ PCF50633_INT2_EXTON3R = 0x40, /* EXTON3 rising edge */
+ PCF50633_INT2_EXTON3F = 0x80, /* EXTON3 falling edge */
+};
+
+enum pcf50633_reg_int3 {
+ PCF50633_INT3_BATFULL = 0x01, /* Battery full */
+ PCF50633_INT3_CHGHALT = 0x02, /* Charger halt */
+ PCF50633_INT3_THLIMON = 0x04,
+ PCF50633_INT3_THLIMOFF = 0x08,
+ PCF50633_INT3_USBLIMON = 0x10,
+ PCF50633_INT3_USBLIMOFF = 0x20,
+ PCF50633_INT3_ADCRDY = 0x40, /* ADC result ready */
+ PCF50633_INT3_ONKEY1S = 0x80, /* ONKEY pressed 1 second */
+};
+
+enum pcf50633_reg_int4 {
+ PCF50633_INT4_LOWSYS = 0x01,
+ PCF50633_INT4_LOWBAT = 0x02,
+ PCF50633_INT4_HIGHTMP = 0x04,
+ PCF50633_INT4_AUTOPWRFAIL = 0x08,
+ PCF50633_INT4_DWN1PWRFAIL = 0x10,
+ PCF50633_INT4_DWN2PWRFAIL = 0x20,
+ PCF50633_INT4_LEDPWRFAIL = 0x40,
+ PCF50633_INT4_LEDOVP = 0x80,
+};
+
+enum pcf50633_reg_int5 {
+ PCF50633_INT5_LDO1PWRFAIL = 0x01,
+ PCF50633_INT5_LDO2PWRFAIL = 0x02,
+ PCF50633_INT5_LDO3PWRFAIL = 0x04,
+ PCF50633_INT5_LDO4PWRFAIL = 0x08,
+ PCF50633_INT5_LDO5PWRFAIL = 0x10,
+ PCF50633_INT5_LDO6PWRFAIL = 0x20,
+ PCF50633_INT5_HCLDOPWRFAIL = 0x40,
+ PCF50633_INT5_HCLDOOVL = 0x80,
+};
+
+/* misc. registers */
+#define PCF50633_REG_OOCSHDWN 0x0c
+
+/* LED registers */
+#define PCF50633_REG_LEDOUT 0x28
+#define PCF50633_REG_LEDENA 0x29
+#define PCF50633_REG_LEDCTL 0x2a
+#define PCF50633_REG_LEDDIM 0x2b
+
+#endif
+
diff --git a/include/linux/mfd/pcf50633/gpio.h b/include/linux/mfd/pcf50633/gpio.h
new file mode 100644
index 0000000..a42b845
--- /dev/null
+++ b/include/linux/mfd/pcf50633/gpio.h
@@ -0,0 +1,52 @@
+/*
+ * gpio.h -- GPIO driver for NXP PCF50633
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __LINUX_MFD_PCF50633_GPIO_H
+#define __LINUX_MFD_PCF50633_GPIO_H
+
+#include <linux/mfd/pcf50633/core.h>
+
+#define PCF50633_GPIO1 1
+#define PCF50633_GPIO2 2
+#define PCF50633_GPIO3 3
+#define PCF50633_GPO 4
+
+#define PCF50633_REG_GPIO1CFG 0x14
+#define PCF50633_REG_GPIO2CFG 0x15
+#define PCF50633_REG_GPIO3CFG 0x16
+#define PCF50633_REG_GPOCFG 0x17
+
+#define PCF50633_GPOCFG_GPOSEL_MASK 0x07
+
+enum pcf50633_reg_gpocfg {
+ PCF50633_GPOCFG_GPOSEL_0 = 0x00,
+ PCF50633_GPOCFG_GPOSEL_LED_NFET = 0x01,
+ PCF50633_GPOCFG_GPOSEL_SYSxOK = 0x02,
+ PCF50633_GPOCFG_GPOSEL_CLK32K = 0x03,
+ PCF50633_GPOCFG_GPOSEL_ADAPUSB = 0x04,
+ PCF50633_GPOCFG_GPOSEL_USBxOK = 0x05,
+ PCF50633_GPOCFG_GPOSEL_ACTPH4 = 0x06,
+ PCF50633_GPOCFG_GPOSEL_1 = 0x07,
+ PCF50633_GPOCFG_GPOSEL_INVERSE = 0x08,
+};
+
+int pcf50633_gpio_set(struct pcf50633 *pcf, int gpio, u8 val);
+u8 pcf50633_gpio_get(struct pcf50633 *pcf, int gpio);
+
+int pcf50633_gpio_invert_set(struct pcf50633 *, int gpio, int invert);
+int pcf50633_gpio_invert_get(struct pcf50633 *pcf, int gpio);
+
+int pcf50633_gpio_power_supply_set(struct pcf50633 *,
+ int gpio, int regulator, int on);
+#endif /* __LINUX_MFD_PCF50633_GPIO_H */
+
+
diff --git a/include/linux/mfd/pcf50633/mbc.h b/include/linux/mfd/pcf50633/mbc.h
new file mode 100644
index 0000000..6e17619
--- /dev/null
+++ b/include/linux/mfd/pcf50633/mbc.h
@@ -0,0 +1,134 @@
+/*
+ * mbc.h -- Driver for NXP PCF50633 Main Battery Charger
+ *
+ * (C) 2006-2008 by Openmoko, Inc.
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __LINUX_MFD_PCF50633_MBC_H
+#define __LINUX_MFD_PCF50633_MBC_H
+
+#include <linux/mfd/pcf50633/core.h>
+#include <linux/platform_device.h>
+
+#define PCF50633_REG_MBCC1 0x43
+#define PCF50633_REG_MBCC2 0x44
+#define PCF50633_REG_MBCC3 0x45
+#define PCF50633_REG_MBCC4 0x46
+#define PCF50633_REG_MBCC5 0x47
+#define PCF50633_REG_MBCC6 0x48
+#define PCF50633_REG_MBCC7 0x49
+#define PCF50633_REG_MBCC8 0x4a
+#define PCF50633_REG_MBCS1 0x4b
+#define PCF50633_REG_MBCS2 0x4c
+#define PCF50633_REG_MBCS3 0x4d
+
+enum pcf50633_reg_mbcc1 {
+ PCF50633_MBCC1_CHGENA = 0x01, /* Charger enable */
+ PCF50633_MBCC1_AUTOSTOP = 0x02,
+ PCF50633_MBCC1_AUTORES = 0x04, /* automatic resume */
+ PCF50633_MBCC1_RESUME = 0x08, /* explicit resume cmd */
+ PCF50633_MBCC1_RESTART = 0x10, /* restart charging */
+ PCF50633_MBCC1_PREWDTIME_60M = 0x20, /* max. precharging time */
+ PCF50633_MBCC1_WDTIME_1H = 0x00,
+ PCF50633_MBCC1_WDTIME_2H = 0x40,
+ PCF50633_MBCC1_WDTIME_4H = 0x80,
+ PCF50633_MBCC1_WDTIME_6H = 0xc0,
+};
+#define PCF50633_MBCC1_WDTIME_MASK 0xc0
+
+enum pcf50633_reg_mbcc2 {
+ PCF50633_MBCC2_VBATCOND_2V7 = 0x00,
+ PCF50633_MBCC2_VBATCOND_2V85 = 0x01,
+ PCF50633_MBCC2_VBATCOND_3V0 = 0x02,
+ PCF50633_MBCC2_VBATCOND_3V15 = 0x03,
+ PCF50633_MBCC2_VMAX_4V = 0x00,
+ PCF50633_MBCC2_VMAX_4V20 = 0x28,
+ PCF50633_MBCC2_VRESDEBTIME_64S = 0x80, /* debounce time (32/64sec) */
+};
+
+enum pcf50633_reg_mbcc7 {
+ PCF50633_MBCC7_USB_100mA = 0x00,
+ PCF50633_MBCC7_USB_500mA = 0x01,
+ PCF50633_MBCC7_USB_1000mA = 0x02,
+ PCF50633_MBCC7_USB_SUSPEND = 0x03,
+ PCF50633_MBCC7_BATTEMP_EN = 0x04,
+ PCF50633_MBCC7_BATSYSIMAX_1A6 = 0x00,
+ PCF50633_MBCC7_BATSYSIMAX_1A8 = 0x40,
+ PCF50633_MBCC7_BATSYSIMAX_2A0 = 0x80,
+ PCF50633_MBCC7_BATSYSIMAX_2A2 = 0xc0,
+};
+#define PCF50633_MBCC7_USB_MASK 0x03
+
+enum pcf50633_reg_mbcc8 {
+ PCF50633_MBCC8_USBENASUS = 0x10,
+};
+
+enum pcf50633_reg_mbcs1 {
+ PCF50633_MBCS1_USBPRES = 0x01,
+ PCF50633_MBCS1_USBOK = 0x02,
+ PCF50633_MBCS1_ADAPTPRES = 0x04,
+ PCF50633_MBCS1_ADAPTOK = 0x08,
+ PCF50633_MBCS1_TBAT_OK = 0x00,
+ PCF50633_MBCS1_TBAT_ABOVE = 0x10,
+ PCF50633_MBCS1_TBAT_BELOW = 0x20,
+ PCF50633_MBCS1_TBAT_UNDEF = 0x30,
+ PCF50633_MBCS1_PREWDTEXP = 0x40,
+ PCF50633_MBCS1_WDTEXP = 0x80,
+};
+
+enum pcf50633_reg_mbcs2_mbcmod {
+ PCF50633_MBCS2_MBC_PLAY = 0x00,
+ PCF50633_MBCS2_MBC_USB_PRE = 0x01,
+ PCF50633_MBCS2_MBC_USB_PRE_WAIT = 0x02,
+ PCF50633_MBCS2_MBC_USB_FAST = 0x03,
+ PCF50633_MBCS2_MBC_USB_FAST_WAIT = 0x04,
+ PCF50633_MBCS2_MBC_USB_SUSPEND = 0x05,
+ PCF50633_MBCS2_MBC_ADP_PRE = 0x06,
+ PCF50633_MBCS2_MBC_ADP_PRE_WAIT = 0x07,
+ PCF50633_MBCS2_MBC_ADP_FAST = 0x08,
+ PCF50633_MBCS2_MBC_ADP_FAST_WAIT = 0x09,
+ PCF50633_MBCS2_MBC_BAT_FULL = 0x0a,
+ PCF50633_MBCS2_MBC_HALT = 0x0b,
+};
+#define PCF50633_MBCS2_MBC_MASK 0x0f
+enum pcf50633_reg_mbcs2_chgstat {
+ PCF50633_MBCS2_CHGS_NONE = 0x00,
+ PCF50633_MBCS2_CHGS_ADAPTER = 0x10,
+ PCF50633_MBCS2_CHGS_USB = 0x20,
+ PCF50633_MBCS2_CHGS_BOTH = 0x30,
+};
+#define PCF50633_MBCS2_RESSTAT_AUTO 0x40
+
+enum pcf50633_reg_mbcs3 {
+ PCF50633_MBCS3_USBLIM_PLAY = 0x01,
+ PCF50633_MBCS3_USBLIM_CGH = 0x02,
+ PCF50633_MBCS3_TLIM_PLAY = 0x04,
+ PCF50633_MBCS3_TLIM_CHG = 0x08,
+ PCF50633_MBCS3_ILIM = 0x10, /* 1: Ibat > Icutoff */
+ PCF50633_MBCS3_VLIM = 0x20, /* 1: Vbat == Vmax */
+ PCF50633_MBCS3_VBATSTAT = 0x40, /* 1: Vbat > Vbatcond */
+ PCF50633_MBCS3_VRES = 0x80, /* 1: Vbat > Vth(RES) */
+};
+
+#define PCF50633_MBCC2_VBATCOND_MASK 0x03
+#define PCF50633_MBCC2_VMAX_MASK 0x3c
+
+/* Charger status */
+#define PCF50633_MBC_USB_ONLINE 0x01
+#define PCF50633_MBC_USB_ACTIVE 0x02
+#define PCF50633_MBC_ADAPTER_ONLINE 0x04
+#define PCF50633_MBC_ADAPTER_ACTIVE 0x08
+
+int pcf50633_mbc_usb_curlim_set(struct pcf50633 *pcf, int ma);
+
+int pcf50633_mbc_get_status(struct pcf50633 *);
+void pcf50633_mbc_set_status(struct pcf50633 *, int what, int status);
+
+#endif
+
diff --git a/include/linux/mfd/pcf50633/pmic.h b/include/linux/mfd/pcf50633/pmic.h
new file mode 100644
index 0000000..2d3dbe5
--- /dev/null
+++ b/include/linux/mfd/pcf50633/pmic.h
@@ -0,0 +1,67 @@
+#ifndef __LINUX_MFD_PCF50633_PMIC_H
+#define __LINUX_MFD_PCF50633_PMIC_H
+
+#include <linux/mfd/pcf50633/core.h>
+#include <linux/platform_device.h>
+
+#define PCF50633_REG_AUTOOUT 0x1a
+#define PCF50633_REG_AUTOENA 0x1b
+#define PCF50633_REG_AUTOCTL 0x1c
+#define PCF50633_REG_AUTOMXC 0x1d
+#define PCF50633_REG_DOWN1OUT 0x1e
+#define PCF50633_REG_DOWN1ENA 0x1f
+#define PCF50633_REG_DOWN1CTL 0x20
+#define PCF50633_REG_DOWN1MXC 0x21
+#define PCF50633_REG_DOWN2OUT 0x22
+#define PCF50633_REG_DOWN2ENA 0x23
+#define PCF50633_REG_DOWN2CTL 0x24
+#define PCF50633_REG_DOWN2MXC 0x25
+#define PCF50633_REG_MEMLDOOUT 0x26
+#define PCF50633_REG_MEMLDOENA 0x27
+#define PCF50633_REG_LDO1OUT 0x2d
+#define PCF50633_REG_LDO1ENA 0x2e
+#define PCF50633_REG_LDO2OUT 0x2f
+#define PCF50633_REG_LDO2ENA 0x30
+#define PCF50633_REG_LDO3OUT 0x31
+#define PCF50633_REG_LDO3ENA 0x32
+#define PCF50633_REG_LDO4OUT 0x33
+#define PCF50633_REG_LDO4ENA 0x34
+#define PCF50633_REG_LDO5OUT 0x35
+#define PCF50633_REG_LDO5ENA 0x36
+#define PCF50633_REG_LDO6OUT 0x37
+#define PCF50633_REG_LDO6ENA 0x38
+#define PCF50633_REG_HCLDOOUT 0x39
+#define PCF50633_REG_HCLDOENA 0x3a
+#define PCF50633_REG_HCLDOOVL 0x40
+
+enum pcf50633_regulator_enable {
+ PCF50633_REGULATOR_ON = 0x01,
+ PCF50633_REGULATOR_ON_GPIO1 = 0x02,
+ PCF50633_REGULATOR_ON_GPIO2 = 0x04,
+ PCF50633_REGULATOR_ON_GPIO3 = 0x08,
+};
+#define PCF50633_REGULATOR_ON_MASK 0x0f
+
+enum pcf50633_regulator_phase {
+ PCF50633_REGULATOR_ACTPH1 = 0x00,
+ PCF50633_REGULATOR_ACTPH2 = 0x10,
+ PCF50633_REGULATOR_ACTPH3 = 0x20,
+ PCF50633_REGULATOR_ACTPH4 = 0x30,
+};
+#define PCF50633_REGULATOR_ACTPH_MASK 0x30
+
+enum pcf50633_regulator_id {
+ PCF50633_REGULATOR_AUTO,
+ PCF50633_REGULATOR_DOWN1,
+ PCF50633_REGULATOR_DOWN2,
+ PCF50633_REGULATOR_LDO1,
+ PCF50633_REGULATOR_LDO2,
+ PCF50633_REGULATOR_LDO3,
+ PCF50633_REGULATOR_LDO4,
+ PCF50633_REGULATOR_LDO5,
+ PCF50633_REGULATOR_LDO6,
+ PCF50633_REGULATOR_HCLDO,
+ PCF50633_REGULATOR_MEMLDO,
+};
+#endif
+
diff --git a/include/linux/smp.h b/include/linux/smp.h
index b824669..715196b 100644
--- a/include/linux/smp.h
+++ b/include/linux/smp.h
@@ -24,6 +24,9 @@ struct call_single_data {
/* total number of cpus in this system (may exceed NR_CPUS) */
extern unsigned int total_cpus;
+int smp_call_function_single(int cpuid, void (*func) (void *info), void *info,
+ int wait);
+
#ifdef CONFIG_SMP
#include <linux/preempt.h>
@@ -79,8 +82,6 @@ smp_call_function_mask(cpumask_t mask, void(*func)(void *info), void *info,
return 0;
}
-int smp_call_function_single(int cpuid, void (*func) (void *info), void *info,
- int wait);
void __smp_call_function_single(int cpuid, struct call_single_data *data);
/*
@@ -140,14 +141,6 @@ static inline int up_smp_call_function(void (*func)(void *), void *info)
static inline void smp_send_reschedule(int cpu) { }
#define num_booting_cpus() 1
#define smp_prepare_boot_cpu() do {} while (0)
-#define smp_call_function_single(cpuid, func, info, wait) \
-({ \
- WARN_ON(cpuid != 0); \
- local_irq_disable(); \
- (func)(info); \
- local_irq_enable(); \
- 0; \
-})
#define smp_call_function_mask(mask, func, info, wait) \
(up_smp_call_function(func, info))
#define smp_call_function_many(mask, func, info, wait) \
diff --git a/include/linux/topology.h b/include/linux/topology.h
index e632d29..a16b9e0 100644
--- a/include/linux/topology.h
+++ b/include/linux/topology.h
@@ -193,5 +193,11 @@ int arch_update_cpu_topology(void);
#ifndef topology_core_siblings
#define topology_core_siblings(cpu) cpumask_of_cpu(cpu)
#endif
+#ifndef topology_thread_cpumask
+#define topology_thread_cpumask(cpu) cpumask_of(cpu)
+#endif
+#ifndef topology_core_cpumask
+#define topology_core_cpumask(cpu) cpumask_of(cpu)
+#endif
#endif /* _LINUX_TOPOLOGY_H */
diff --git a/include/net/wimax.h b/include/net/wimax.h
index 073809c..6b3824e 100644
--- a/include/net/wimax.h
+++ b/include/net/wimax.h
@@ -323,8 +323,8 @@ struct input_dev;
*
* @rf_hw: [private] State of the hardware radio switch (OFF/ON)
*
- * @debufs_dentry: [private] Used to hook up a debugfs entry. This
- * shows up in the debugfs root as wimax:DEVICENAME.
+ * @debugfs_dentry: [private] Used to hook up a debugfs entry. This
+ * shows up in the debugfs root as wimax\:DEVICENAME.
*
* Description:
* This structure defines a common interface to access all WiMAX
diff --git a/include/sound/soc-dapm.h b/include/sound/soc-dapm.h
index 4af1083..93a4edb 100644
--- a/include/sound/soc-dapm.h
+++ b/include/sound/soc-dapm.h
@@ -178,7 +178,7 @@
.private_value = (unsigned long)&xenum }
#define SOC_DAPM_VALUE_ENUM(xname, xenum) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
- .info = snd_soc_info_value_enum_double, \
+ .info = snd_soc_info_enum_double, \
.get = snd_soc_dapm_get_value_enum_double, \
.put = snd_soc_dapm_put_value_enum_double, \
.private_value = (unsigned long)&xenum }
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 9b930d3..24593ac 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -106,7 +106,7 @@
.private_value = (unsigned long)&xenum }
#define SOC_VALUE_ENUM(xname, xenum) \
{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname,\
- .info = snd_soc_info_value_enum_double, \
+ .info = snd_soc_info_enum_double, \
.get = snd_soc_get_value_enum_double, \
.put = snd_soc_put_value_enum_double, \
.private_value = (unsigned long)&xenum }
@@ -211,8 +211,6 @@ int snd_soc_get_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
-int snd_soc_info_value_enum_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo);
int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol);
int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
@@ -419,17 +417,6 @@ struct soc_enum {
unsigned char shift_l;
unsigned char shift_r;
unsigned int max;
- const char **texts;
- void *dapm;
-};
-
-/* semi enumerated kcontrol */
-struct soc_value_enum {
- unsigned short reg;
- unsigned short reg2;
- unsigned char shift_l;
- unsigned char shift_r;
- unsigned int max;
unsigned int mask;
const char **texts;
const unsigned int *values;
diff --git a/kernel/Makefile b/kernel/Makefile
index 8b2628c..e411592 100644
--- a/kernel/Makefile
+++ b/kernel/Makefile
@@ -40,7 +40,11 @@ obj-$(CONFIG_RT_MUTEXES) += rtmutex.o
obj-$(CONFIG_DEBUG_RT_MUTEXES) += rtmutex-debug.o
obj-$(CONFIG_RT_MUTEX_TESTER) += rtmutex-tester.o
obj-$(CONFIG_GENERIC_ISA_DMA) += dma.o
-obj-$(CONFIG_USE_GENERIC_SMP_HELPERS) += smp.o
+ifeq ($(CONFIG_USE_GENERIC_SMP_HELPERS),y)
+obj-y += smp.o
+else
+obj-y += up.o
+endif
obj-$(CONFIG_SMP) += spinlock.o
obj-$(CONFIG_DEBUG_SPINLOCK) += spinlock.o
obj-$(CONFIG_PROVE_LOCKING) += spinlock.o
diff --git a/kernel/async.c b/kernel/async.c
index f286e9f..608b32b 100644
--- a/kernel/async.c
+++ b/kernel/async.c
@@ -90,12 +90,12 @@ extern int initcall_debug;
static async_cookie_t __lowest_in_progress(struct list_head *running)
{
struct async_entry *entry;
- if (!list_empty(&async_pending)) {
- entry = list_first_entry(&async_pending,
+ if (!list_empty(running)) {
+ entry = list_first_entry(running,
struct async_entry, list);
return entry->cookie;
- } else if (!list_empty(running)) {
- entry = list_first_entry(running,
+ } else if (!list_empty(&async_pending)) {
+ entry = list_first_entry(&async_pending,
struct async_entry, list);
return entry->cookie;
} else {
@@ -104,6 +104,17 @@ static async_cookie_t __lowest_in_progress(struct list_head *running)
}
}
+
+static async_cookie_t lowest_in_progress(struct list_head *running)
+{
+ unsigned long flags;
+ async_cookie_t ret;
+
+ spin_lock_irqsave(&async_lock, flags);
+ ret = __lowest_in_progress(running);
+ spin_unlock_irqrestore(&async_lock, flags);
+ return ret;
+}
/*
* pick the first pending entry and run it
*/
@@ -229,7 +240,7 @@ void async_synchronize_cookie_special(async_cookie_t cookie, struct list_head *r
starttime = ktime_get();
}
- wait_event(async_done, __lowest_in_progress(running) >= cookie);
+ wait_event(async_done, lowest_in_progress(running) >= cookie);
if (initcall_debug && system_state == SYSTEM_BOOTING) {
endtime = ktime_get();
diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c
index f63c706..c248eba 100644
--- a/kernel/irq/chip.c
+++ b/kernel/irq/chip.c
@@ -46,7 +46,10 @@ void dynamic_irq_init(unsigned int irq)
desc->irq_count = 0;
desc->irqs_unhandled = 0;
#ifdef CONFIG_SMP
- cpumask_setall(&desc->affinity);
+ cpumask_setall(desc->affinity);
+#ifdef CONFIG_GENERIC_PENDING_IRQ
+ cpumask_clear(desc->pending_mask);
+#endif
#endif
spin_unlock_irqrestore(&desc->lock, flags);
}
diff --git a/kernel/irq/handle.c b/kernel/irq/handle.c
index c20db0b..375d68c 100644
--- a/kernel/irq/handle.c
+++ b/kernel/irq/handle.c
@@ -17,6 +17,7 @@
#include <linux/kernel_stat.h>
#include <linux/rculist.h>
#include <linux/hash.h>
+#include <linux/bootmem.h>
#include "internals.h"
@@ -57,6 +58,7 @@ int nr_irqs = NR_IRQS;
EXPORT_SYMBOL_GPL(nr_irqs);
#ifdef CONFIG_SPARSE_IRQ
+
static struct irq_desc irq_desc_init = {
.irq = -1,
.status = IRQ_DISABLED,
@@ -64,9 +66,6 @@ static struct irq_desc irq_desc_init = {
.handle_irq = handle_bad_irq,
.depth = 1,
.lock = __SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
-#ifdef CONFIG_SMP
- .affinity = CPU_MASK_ALL
-#endif
};
void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr)
@@ -101,6 +100,10 @@ static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu)
printk(KERN_ERR "can not alloc kstat_irqs\n");
BUG_ON(1);
}
+ if (!init_alloc_desc_masks(desc, cpu, false)) {
+ printk(KERN_ERR "can not alloc irq_desc cpumasks\n");
+ BUG_ON(1);
+ }
arch_init_chip_data(desc, cpu);
}
@@ -109,7 +112,7 @@ static void init_one_irq_desc(int irq, struct irq_desc *desc, int cpu)
*/
DEFINE_SPINLOCK(sparse_irq_lock);
-struct irq_desc *irq_desc_ptrs[NR_IRQS] __read_mostly;
+struct irq_desc **irq_desc_ptrs __read_mostly;
static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_smp = {
[0 ... NR_IRQS_LEGACY-1] = {
@@ -119,14 +122,10 @@ static struct irq_desc irq_desc_legacy[NR_IRQS_LEGACY] __cacheline_aligned_in_sm
.handle_irq = handle_bad_irq,
.depth = 1,
.lock = __SPIN_LOCK_UNLOCKED(irq_desc_init.lock),
-#ifdef CONFIG_SMP
- .affinity = CPU_MASK_ALL
-#endif
}
};
-/* FIXME: use bootmem alloc ...*/
-static unsigned int kstat_irqs_legacy[NR_IRQS_LEGACY][NR_CPUS];
+static unsigned int *kstat_irqs_legacy;
int __init early_irq_init(void)
{
@@ -134,18 +133,30 @@ int __init early_irq_init(void)
int legacy_count;
int i;
+ /* initialize nr_irqs based on nr_cpu_ids */
+ arch_probe_nr_irqs();
+ printk(KERN_INFO "NR_IRQS:%d nr_irqs:%d\n", NR_IRQS, nr_irqs);
+
desc = irq_desc_legacy;
legacy_count = ARRAY_SIZE(irq_desc_legacy);
+ /* allocate irq_desc_ptrs array based on nr_irqs */
+ irq_desc_ptrs = alloc_bootmem(nr_irqs * sizeof(void *));
+
+ /* allocate based on nr_cpu_ids */
+ /* FIXME: invert kstat_irgs, and it'd be a per_cpu_alloc'd thing */
+ kstat_irqs_legacy = alloc_bootmem(NR_IRQS_LEGACY * nr_cpu_ids *
+ sizeof(int));
+
for (i = 0; i < legacy_count; i++) {
desc[i].irq = i;
- desc[i].kstat_irqs = kstat_irqs_legacy[i];
+ desc[i].kstat_irqs = kstat_irqs_legacy + i * nr_cpu_ids;
lockdep_set_class(&desc[i].lock, &irq_desc_lock_class);
-
+ init_alloc_desc_masks(&desc[i], 0, true);
irq_desc_ptrs[i] = desc + i;
}
- for (i = legacy_count; i < NR_IRQS; i++)
+ for (i = legacy_count; i < nr_irqs; i++)
irq_desc_ptrs[i] = NULL;
return arch_early_irq_init();
@@ -153,7 +164,10 @@ int __init early_irq_init(void)
struct irq_desc *irq_to_desc(unsigned int irq)
{
- return (irq < NR_IRQS) ? irq_desc_ptrs[irq] : NULL;
+ if (irq_desc_ptrs && irq < nr_irqs)
+ return irq_desc_ptrs[irq];
+
+ return NULL;
}
struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu)
@@ -162,10 +176,9 @@ struct irq_desc *irq_to_desc_alloc_cpu(unsigned int irq, int cpu)
unsigned long flags;
int node;
- if (irq >= NR_IRQS) {
- printk(KERN_WARNING "irq >= NR_IRQS in irq_to_desc_alloc: %d %d\n",
- irq, NR_IRQS);
- WARN_ON(1);
+ if (irq >= nr_irqs) {
+ WARN(1, "irq (%d) >= nr_irqs (%d) in irq_to_desc_alloc\n",
+ irq, nr_irqs);
return NULL;
}
@@ -207,9 +220,6 @@ struct irq_desc irq_desc[NR_IRQS] __cacheline_aligned_in_smp = {
.handle_irq = handle_bad_irq,
.depth = 1,
.lock = __SPIN_LOCK_UNLOCKED(irq_desc->lock),
-#ifdef CONFIG_SMP
- .affinity = CPU_MASK_ALL
-#endif
}
};
@@ -219,12 +229,15 @@ int __init early_irq_init(void)
int count;
int i;
+ printk(KERN_INFO "NR_IRQS:%d\n", NR_IRQS);
+
desc = irq_desc;
count = ARRAY_SIZE(irq_desc);
- for (i = 0; i < count; i++)
+ for (i = 0; i < count; i++) {
desc[i].irq = i;
-
+ init_alloc_desc_masks(&desc[i], 0, true);
+ }
return arch_early_irq_init();
}
diff --git a/kernel/irq/internals.h b/kernel/irq/internals.h
index e6d0a43..40416a8 100644
--- a/kernel/irq/internals.h
+++ b/kernel/irq/internals.h
@@ -16,7 +16,14 @@ extern int __irq_set_trigger(struct irq_desc *desc, unsigned int irq,
extern struct lock_class_key irq_desc_lock_class;
extern void init_kstat_irqs(struct irq_desc *desc, int cpu, int nr);
extern spinlock_t sparse_irq_lock;
+
+#ifdef CONFIG_SPARSE_IRQ
+/* irq_desc_ptrs allocated at boot time */
+extern struct irq_desc **irq_desc_ptrs;
+#else
+/* irq_desc_ptrs is a fixed size array */
extern struct irq_desc *irq_desc_ptrs[NR_IRQS];
+#endif
#ifdef CONFIG_PROC_FS
extern void register_irq_proc(unsigned int irq, struct irq_desc *desc);
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c
index cd0cd8d..b98739a 100644
--- a/kernel/irq/manage.c
+++ b/kernel/irq/manage.c
@@ -98,14 +98,14 @@ int irq_set_affinity(unsigned int irq, const struct cpumask *cpumask)
#ifdef CONFIG_GENERIC_PENDING_IRQ
if (desc->status & IRQ_MOVE_PCNTXT || desc->status & IRQ_DISABLED) {
- cpumask_copy(&desc->affinity, cpumask);
+ cpumask_copy(desc->affinity, cpumask);
desc->chip->set_affinity(irq, cpumask);
} else {
desc->status |= IRQ_MOVE_PENDING;
- cpumask_copy(&desc->pending_mask, cpumask);
+ cpumask_copy(desc->pending_mask, cpumask);
}
#else
- cpumask_copy(&desc->affinity, cpumask);
+ cpumask_copy(desc->affinity, cpumask);
desc->chip->set_affinity(irq, cpumask);
#endif
desc->status |= IRQ_AFFINITY_SET;
@@ -127,16 +127,16 @@ int do_irq_select_affinity(unsigned int irq, struct irq_desc *desc)
* one of the targets is online.
*/
if (desc->status & (IRQ_AFFINITY_SET | IRQ_NO_BALANCING)) {
- if (cpumask_any_and(&desc->affinity, cpu_online_mask)
+ if (cpumask_any_and(desc->affinity, cpu_online_mask)
< nr_cpu_ids)
goto set_affinity;
else
desc->status &= ~IRQ_AFFINITY_SET;
}
- cpumask_and(&desc->affinity, cpu_online_mask, irq_default_affinity);
+ cpumask_and(desc->affinity, cpu_online_mask, irq_default_affinity);
set_affinity:
- desc->chip->set_affinity(irq, &desc->affinity);
+ desc->chip->set_affinity(irq, desc->affinity);
return 0;
}
diff --git a/kernel/irq/migration.c b/kernel/irq/migration.c
index bd72329..e05ad9b 100644
--- a/kernel/irq/migration.c
+++ b/kernel/irq/migration.c
@@ -18,7 +18,7 @@ void move_masked_irq(int irq)
desc->status &= ~IRQ_MOVE_PENDING;
- if (unlikely(cpumask_empty(&desc->pending_mask)))
+ if (unlikely(cpumask_empty(desc->pending_mask)))
return;
if (!desc->chip->set_affinity)
@@ -38,13 +38,13 @@ void move_masked_irq(int irq)
* For correct operation this depends on the caller
* masking the irqs.
*/
- if (likely(cpumask_any_and(&desc->pending_mask, cpu_online_mask)
+ if (likely(cpumask_any_and(desc->pending_mask, cpu_online_mask)
< nr_cpu_ids)) {
- cpumask_and(&desc->affinity,
- &desc->pending_mask, cpu_online_mask);
- desc->chip->set_affinity(irq, &desc->affinity);
+ cpumask_and(desc->affinity,
+ desc->pending_mask, cpu_online_mask);
+ desc->chip->set_affinity(irq, desc->affinity);
}
- cpumask_clear(&desc->pending_mask);
+ cpumask_clear(desc->pending_mask);
}
void move_native_irq(int irq)
diff --git a/kernel/irq/numa_migrate.c b/kernel/irq/numa_migrate.c
index ecf765c..666260e 100644
--- a/kernel/irq/numa_migrate.c
+++ b/kernel/irq/numa_migrate.c
@@ -38,15 +38,22 @@ static void free_kstat_irqs(struct irq_desc *old_desc, struct irq_desc *desc)
old_desc->kstat_irqs = NULL;
}
-static void init_copy_one_irq_desc(int irq, struct irq_desc *old_desc,
+static bool init_copy_one_irq_desc(int irq, struct irq_desc *old_desc,
struct irq_desc *desc, int cpu)
{
memcpy(desc, old_desc, sizeof(struct irq_desc));
+ if (!init_alloc_desc_masks(desc, cpu, false)) {
+ printk(KERN_ERR "irq %d: can not get new irq_desc cpumask "
+ "for migration.\n", irq);
+ return false;
+ }
spin_lock_init(&desc->lock);
desc->cpu = cpu;
lockdep_set_class(&desc->lock, &irq_desc_lock_class);
init_copy_kstat_irqs(old_desc, desc, cpu, nr_cpu_ids);
+ init_copy_desc_masks(old_desc, desc);
arch_init_copy_chip_data(old_desc, desc, cpu);
+ return true;
}
static void free_one_irq_desc(struct irq_desc *old_desc, struct irq_desc *desc)
@@ -76,12 +83,18 @@ static struct irq_desc *__real_move_irq_desc(struct irq_desc *old_desc,
node = cpu_to_node(cpu);
desc = kzalloc_node(sizeof(*desc), GFP_ATOMIC, node);
if (!desc) {
- printk(KERN_ERR "irq %d: can not get new irq_desc for migration.\n", irq);
+ printk(KERN_ERR "irq %d: can not get new irq_desc "
+ "for migration.\n", irq);
+ /* still use old one */
+ desc = old_desc;
+ goto out_unlock;
+ }
+ if (!init_copy_one_irq_desc(irq, old_desc, desc, cpu)) {
/* still use old one */
+ kfree(desc);
desc = old_desc;
goto out_unlock;
}
- init_copy_one_irq_desc(irq, old_desc, desc, cpu);
irq_desc_ptrs[irq] = desc;
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index aae3f74..692363d 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -20,11 +20,11 @@ static struct proc_dir_entry *root_irq_dir;
static int irq_affinity_proc_show(struct seq_file *m, void *v)
{
struct irq_desc *desc = irq_to_desc((long)m->private);
- const struct cpumask *mask = &desc->affinity;
+ const struct cpumask *mask = desc->affinity;
#ifdef CONFIG_GENERIC_PENDING_IRQ
if (desc->status & IRQ_MOVE_PENDING)
- mask = &desc->pending_mask;
+ mask = desc->pending_mask;
#endif
seq_cpumask(m, mask);
seq_putc(m, '\n');
diff --git a/kernel/rcutorture.c b/kernel/rcutorture.c
index 1cff28d..7c4142a 100644
--- a/kernel/rcutorture.c
+++ b/kernel/rcutorture.c
@@ -136,29 +136,47 @@ static int stutter_pause_test = 0;
#endif
int rcutorture_runnable = RCUTORTURE_RUNNABLE_INIT;
-#define FULLSTOP_SHUTDOWN 1 /* Bail due to system shutdown/panic. */
-#define FULLSTOP_CLEANUP 2 /* Orderly shutdown. */
-static int fullstop; /* stop generating callbacks at test end. */
-DEFINE_MUTEX(fullstop_mutex); /* protect fullstop transitions and */
- /* spawning of kthreads. */
+/* Mediate rmmod and system shutdown. Concurrent rmmod & shutdown illegal! */
+
+#define FULLSTOP_DONTSTOP 0 /* Normal operation. */
+#define FULLSTOP_SHUTDOWN 1 /* System shutdown with rcutorture running. */
+#define FULLSTOP_RMMOD 2 /* Normal rmmod of rcutorture. */
+static int fullstop = FULLSTOP_RMMOD;
+DEFINE_MUTEX(fullstop_mutex); /* Protect fullstop transitions and spawning */
+ /* of kthreads. */
/*
- * Detect and respond to a signal-based shutdown.
+ * Detect and respond to a system shutdown.
*/
static int
rcutorture_shutdown_notify(struct notifier_block *unused1,
unsigned long unused2, void *unused3)
{
- if (fullstop)
- return NOTIFY_DONE;
mutex_lock(&fullstop_mutex);
- if (!fullstop)
+ if (fullstop == FULLSTOP_DONTSTOP)
fullstop = FULLSTOP_SHUTDOWN;
+ else
+ printk(KERN_WARNING /* but going down anyway, so... */
+ "Concurrent 'rmmod rcutorture' and shutdown illegal!\n");
mutex_unlock(&fullstop_mutex);
return NOTIFY_DONE;
}
/*
+ * Absorb kthreads into a kernel function that won't return, so that
+ * they won't ever access module text or data again.
+ */
+static void rcutorture_shutdown_absorb(char *title)
+{
+ if (ACCESS_ONCE(fullstop) == FULLSTOP_SHUTDOWN) {
+ printk(KERN_NOTICE
+ "rcutorture thread %s parking due to system shutdown\n",
+ title);
+ schedule_timeout_uninterruptible(MAX_SCHEDULE_TIMEOUT);
+ }
+}
+
+/*
* Allocate an element from the rcu_tortures pool.
*/
static struct rcu_torture *
@@ -219,13 +237,14 @@ rcu_random(struct rcu_random_state *rrsp)
}
static void
-rcu_stutter_wait(void)
+rcu_stutter_wait(char *title)
{
- while ((stutter_pause_test || !rcutorture_runnable) && !fullstop) {
+ while (stutter_pause_test || !rcutorture_runnable) {
if (rcutorture_runnable)
schedule_timeout_interruptible(1);
else
schedule_timeout_interruptible(round_jiffies_relative(HZ));
+ rcutorture_shutdown_absorb(title);
}
}
@@ -287,7 +306,7 @@ rcu_torture_cb(struct rcu_head *p)
int i;
struct rcu_torture *rp = container_of(p, struct rcu_torture, rtort_rcu);
- if (fullstop) {
+ if (fullstop != FULLSTOP_DONTSTOP) {
/* Test is ending, just drop callbacks on the floor. */
/* The next initialization will pick up the pieces. */
return;
@@ -619,10 +638,11 @@ rcu_torture_writer(void *arg)
}
rcu_torture_current_version++;
oldbatch = cur_ops->completed();
- rcu_stutter_wait();
- } while (!kthread_should_stop() && !fullstop);
+ rcu_stutter_wait("rcu_torture_writer");
+ } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
VERBOSE_PRINTK_STRING("rcu_torture_writer task stopping");
- while (!kthread_should_stop() && fullstop != FULLSTOP_SHUTDOWN)
+ rcutorture_shutdown_absorb("rcu_torture_writer");
+ while (!kthread_should_stop())
schedule_timeout_uninterruptible(1);
return 0;
}
@@ -643,11 +663,12 @@ rcu_torture_fakewriter(void *arg)
schedule_timeout_uninterruptible(1 + rcu_random(&rand)%10);
udelay(rcu_random(&rand) & 0x3ff);
cur_ops->sync();
- rcu_stutter_wait();
- } while (!kthread_should_stop() && !fullstop);
+ rcu_stutter_wait("rcu_torture_fakewriter");
+ } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
VERBOSE_PRINTK_STRING("rcu_torture_fakewriter task stopping");
- while (!kthread_should_stop() && fullstop != FULLSTOP_SHUTDOWN)
+ rcutorture_shutdown_absorb("rcu_torture_fakewriter");
+ while (!kthread_should_stop())
schedule_timeout_uninterruptible(1);
return 0;
}
@@ -752,12 +773,13 @@ rcu_torture_reader(void *arg)
preempt_enable();
cur_ops->readunlock(idx);
schedule();
- rcu_stutter_wait();
- } while (!kthread_should_stop() && !fullstop);
+ rcu_stutter_wait("rcu_torture_reader");
+ } while (!kthread_should_stop() && fullstop == FULLSTOP_DONTSTOP);
VERBOSE_PRINTK_STRING("rcu_torture_reader task stopping");
+ rcutorture_shutdown_absorb("rcu_torture_reader");
if (irqreader && cur_ops->irqcapable)
del_timer_sync(&t);
- while (!kthread_should_stop() && fullstop != FULLSTOP_SHUTDOWN)
+ while (!kthread_should_stop())
schedule_timeout_uninterruptible(1);
return 0;
}
@@ -854,7 +876,8 @@ rcu_torture_stats(void *arg)
do {
schedule_timeout_interruptible(stat_interval * HZ);
rcu_torture_stats_print();
- } while (!kthread_should_stop() && !fullstop);
+ rcutorture_shutdown_absorb("rcu_torture_stats");
+ } while (!kthread_should_stop());
VERBOSE_PRINTK_STRING("rcu_torture_stats task stopping");
return 0;
}
@@ -866,52 +889,49 @@ static int rcu_idle_cpu; /* Force all torture tasks off this CPU */
*/
static void rcu_torture_shuffle_tasks(void)
{
- cpumask_var_t tmp_mask;
+ cpumask_t tmp_mask;
int i;
- if (!alloc_cpumask_var(&tmp_mask, GFP_KERNEL))
- BUG();
-
- cpumask_setall(tmp_mask);
+ cpus_setall(tmp_mask);
get_online_cpus();
/* No point in shuffling if there is only one online CPU (ex: UP) */
- if (num_online_cpus() == 1)
- goto out;
+ if (num_online_cpus() == 1) {
+ put_online_cpus();
+ return;
+ }
if (rcu_idle_cpu != -1)
- cpumask_clear_cpu(rcu_idle_cpu, tmp_mask);
+ cpu_clear(rcu_idle_cpu, tmp_mask);
- set_cpus_allowed_ptr(current, tmp_mask);
+ set_cpus_allowed_ptr(current, &tmp_mask);
if (reader_tasks) {
for (i = 0; i < nrealreaders; i++)
if (reader_tasks[i])
set_cpus_allowed_ptr(reader_tasks[i],
- tmp_mask);
+ &tmp_mask);
}
if (fakewriter_tasks) {
for (i = 0; i < nfakewriters; i++)
if (fakewriter_tasks[i])
set_cpus_allowed_ptr(fakewriter_tasks[i],
- tmp_mask);
+ &tmp_mask);
}
if (writer_task)
- set_cpus_allowed_ptr(writer_task, tmp_mask);
+ set_cpus_allowed_ptr(writer_task, &tmp_mask);
if (stats_task)
- set_cpus_allowed_ptr(stats_task, tmp_mask);
+ set_cpus_allowed_ptr(stats_task, &tmp_mask);
if (rcu_idle_cpu == -1)
rcu_idle_cpu = num_online_cpus() - 1;
else
rcu_idle_cpu--;
-out:
put_online_cpus();
- free_cpumask_var(tmp_mask);
}
/* Shuffle tasks across CPUs, with the intent of allowing each CPU in the
@@ -925,7 +945,8 @@ rcu_torture_shuffle(void *arg)
do {
schedule_timeout_interruptible(shuffle_interval * HZ);
rcu_torture_shuffle_tasks();
- } while (!kthread_should_stop() && !fullstop);
+ rcutorture_shutdown_absorb("rcu_torture_shuffle");
+ } while (!kthread_should_stop());
VERBOSE_PRINTK_STRING("rcu_torture_shuffle task stopping");
return 0;
}
@@ -940,10 +961,11 @@ rcu_torture_stutter(void *arg)
do {
schedule_timeout_interruptible(stutter * HZ);
stutter_pause_test = 1;
- if (!kthread_should_stop() && !fullstop)
+ if (!kthread_should_stop())
schedule_timeout_interruptible(stutter * HZ);
stutter_pause_test = 0;
- } while (!kthread_should_stop() && !fullstop);
+ rcutorture_shutdown_absorb("rcu_torture_stutter");
+ } while (!kthread_should_stop());
VERBOSE_PRINTK_STRING("rcu_torture_stutter task stopping");
return 0;
}
@@ -970,15 +992,16 @@ rcu_torture_cleanup(void)
int i;
mutex_lock(&fullstop_mutex);
- if (!fullstop) {
- /* If being signaled, let it happen, then exit. */
+ if (fullstop == FULLSTOP_SHUTDOWN) {
+ printk(KERN_WARNING /* but going down anyway, so... */
+ "Concurrent 'rmmod rcutorture' and shutdown illegal!\n");
mutex_unlock(&fullstop_mutex);
- schedule_timeout_interruptible(10 * HZ);
+ schedule_timeout_uninterruptible(10);
if (cur_ops->cb_barrier != NULL)
cur_ops->cb_barrier();
return;
}
- fullstop = FULLSTOP_CLEANUP;
+ fullstop = FULLSTOP_RMMOD;
mutex_unlock(&fullstop_mutex);
unregister_reboot_notifier(&rcutorture_nb);
if (stutter_task) {
@@ -1078,7 +1101,7 @@ rcu_torture_init(void)
else
nrealreaders = 2 * num_online_cpus();
rcu_torture_print_module_parms("Start of test");
- fullstop = 0;
+ fullstop = FULLSTOP_DONTSTOP;
/* Set up the freelist. */
diff --git a/kernel/sched.c b/kernel/sched.c
index 43fd212..ce9feca 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -125,6 +125,9 @@ DEFINE_TRACE(sched_switch);
DEFINE_TRACE(sched_migrate_task);
#ifdef CONFIG_SMP
+
+static void double_rq_lock(struct rq *rq1, struct rq *rq2);
+
/*
* Divide a load by a sched group cpu_power : (load / sg->__cpu_power)
* Since cpu_power is a 'constant', we can use a reciprocal divide.
@@ -7352,10 +7355,10 @@ cpu_to_phys_group(int cpu, const struct cpumask *cpu_map,
* groups, so roll our own. Now each node has its own list of groups which
* gets dynamically allocated.
*/
-static DEFINE_PER_CPU(struct sched_domain, node_domains);
+static DEFINE_PER_CPU(struct static_sched_domain, node_domains);
static struct sched_group ***sched_group_nodes_bycpu;
-static DEFINE_PER_CPU(struct sched_domain, allnodes_domains);
+static DEFINE_PER_CPU(struct static_sched_domain, allnodes_domains);
static DEFINE_PER_CPU(struct static_sched_group, sched_group_allnodes);
static int cpu_to_allnodes_group(int cpu, const struct cpumask *cpu_map,
@@ -7630,7 +7633,7 @@ static int __build_sched_domains(const struct cpumask *cpu_map,
#ifdef CONFIG_NUMA
if (cpumask_weight(cpu_map) >
SD_NODES_PER_DOMAIN*cpumask_weight(nodemask)) {
- sd = &per_cpu(allnodes_domains, i);
+ sd = &per_cpu(allnodes_domains, i).sd;
SD_INIT(sd, ALLNODES);
set_domain_attribute(sd, attr);
cpumask_copy(sched_domain_span(sd), cpu_map);
@@ -7640,7 +7643,7 @@ static int __build_sched_domains(const struct cpumask *cpu_map,
} else
p = NULL;
- sd = &per_cpu(node_domains, i);
+ sd = &per_cpu(node_domains, i).sd;
SD_INIT(sd, NODE);
set_domain_attribute(sd, attr);
sched_domain_node_span(cpu_to_node(i), sched_domain_span(sd));
@@ -7758,7 +7761,7 @@ static int __build_sched_domains(const struct cpumask *cpu_map,
for_each_cpu(j, nodemask) {
struct sched_domain *sd;
- sd = &per_cpu(node_domains, j);
+ sd = &per_cpu(node_domains, j).sd;
sd->groups = sg;
}
sg->__cpu_power = 0;
diff --git a/kernel/sched_debug.c b/kernel/sched_debug.c
index 4293cfa..16eeba4e 100644
--- a/kernel/sched_debug.c
+++ b/kernel/sched_debug.c
@@ -145,6 +145,19 @@ static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu)
read_unlock_irqrestore(&tasklist_lock, flags);
}
+#if defined(CONFIG_CGROUP_SCHED) && \
+ (defined(CONFIG_FAIR_GROUP_SCHED) || defined(CONFIG_RT_GROUP_SCHED))
+static void task_group_path(struct task_group *tg, char *buf, int buflen)
+{
+ /* may be NULL if the underlying cgroup isn't fully-created yet */
+ if (!tg->css.cgroup) {
+ buf[0] = '\0';
+ return;
+ }
+ cgroup_path(tg->css.cgroup, buf, buflen);
+}
+#endif
+
void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
{
s64 MIN_vruntime = -1, min_vruntime, max_vruntime = -1,
@@ -154,10 +167,10 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
unsigned long flags;
#if defined(CONFIG_CGROUP_SCHED) && defined(CONFIG_FAIR_GROUP_SCHED)
- char path[128] = "";
+ char path[128];
struct task_group *tg = cfs_rq->tg;
- cgroup_path(tg->css.cgroup, path, sizeof(path));
+ task_group_path(tg, path, sizeof(path));
SEQ_printf(m, "\ncfs_rq[%d]:%s\n", cpu, path);
#elif defined(CONFIG_USER_SCHED) && defined(CONFIG_FAIR_GROUP_SCHED)
@@ -208,10 +221,10 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)
void print_rt_rq(struct seq_file *m, int cpu, struct rt_rq *rt_rq)
{
#if defined(CONFIG_CGROUP_SCHED) && defined(CONFIG_RT_GROUP_SCHED)
- char path[128] = "";
+ char path[128];
struct task_group *tg = rt_rq->tg;
- cgroup_path(tg->css.cgroup, path, sizeof(path));
+ task_group_path(tg, path, sizeof(path));
SEQ_printf(m, "\nrt_rq[%d]:%s\n", cpu, path);
#else
diff --git a/kernel/sched_rt.c b/kernel/sched_rt.c
index 954e1a8..da932f4 100644
--- a/kernel/sched_rt.c
+++ b/kernel/sched_rt.c
@@ -960,16 +960,17 @@ static struct task_struct *pick_next_highest_task_rt(struct rq *rq, int cpu)
static DEFINE_PER_CPU(cpumask_var_t, local_cpu_mask);
-static inline int pick_optimal_cpu(int this_cpu, cpumask_t *mask)
+static inline int pick_optimal_cpu(int this_cpu,
+ const struct cpumask *mask)
{
int first;
/* "this_cpu" is cheaper to preempt than a remote processor */
- if ((this_cpu != -1) && cpu_isset(this_cpu, *mask))
+ if ((this_cpu != -1) && cpumask_test_cpu(this_cpu, mask))
return this_cpu;
- first = first_cpu(*mask);
- if (first != NR_CPUS)
+ first = cpumask_first(mask);
+ if (first < nr_cpu_ids)
return first;
return -1;
@@ -981,6 +982,7 @@ static int find_lowest_rq(struct task_struct *task)
struct cpumask *lowest_mask = __get_cpu_var(local_cpu_mask);
int this_cpu = smp_processor_id();
int cpu = task_cpu(task);
+ cpumask_var_t domain_mask;
if (task->rt.nr_cpus_allowed == 1)
return -1; /* No other targets possible */
@@ -1013,19 +1015,25 @@ static int find_lowest_rq(struct task_struct *task)
if (this_cpu == cpu)
this_cpu = -1; /* Skip this_cpu opt if the same */
- for_each_domain(cpu, sd) {
- if (sd->flags & SD_WAKE_AFFINE) {
- cpumask_t domain_mask;
- int best_cpu;
+ if (alloc_cpumask_var(&domain_mask, GFP_ATOMIC)) {
+ for_each_domain(cpu, sd) {
+ if (sd->flags & SD_WAKE_AFFINE) {
+ int best_cpu;
- cpumask_and(&domain_mask, sched_domain_span(sd),
- lowest_mask);
+ cpumask_and(domain_mask,
+ sched_domain_span(sd),
+ lowest_mask);
- best_cpu = pick_optimal_cpu(this_cpu,
- &domain_mask);
- if (best_cpu != -1)
- return best_cpu;
+ best_cpu = pick_optimal_cpu(this_cpu,
+ domain_mask);
+
+ if (best_cpu != -1) {
+ free_cpumask_var(domain_mask);
+ return best_cpu;
+ }
+ }
}
+ free_cpumask_var(domain_mask);
}
/*
diff --git a/kernel/softirq.c b/kernel/softirq.c
index bdbe9de..0365b48 100644
--- a/kernel/softirq.c
+++ b/kernel/softirq.c
@@ -795,6 +795,11 @@ int __init __weak early_irq_init(void)
return 0;
}
+int __init __weak arch_probe_nr_irqs(void)
+{
+ return 0;
+}
+
int __init __weak arch_early_irq_init(void)
{
return 0;
diff --git a/kernel/up.c b/kernel/up.c
new file mode 100644
index 0000000..1ff27a2
--- /dev/null
+++ b/kernel/up.c
@@ -0,0 +1,21 @@
+/*
+ * Uniprocessor-only support functions. The counterpart to kernel/smp.c
+ */
+
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/smp.h>
+
+int smp_call_function_single(int cpu, void (*func) (void *info), void *info,
+ int wait)
+{
+ WARN_ON(cpu != 0);
+
+ local_irq_disable();
+ (func)(info);
+ local_irq_enable();
+
+ return 0;
+}
+EXPORT_SYMBOL(smp_call_function_single);
diff --git a/lib/smp_processor_id.c b/lib/smp_processor_id.c
index 0f8fc22..4689cb0 100644
--- a/lib/smp_processor_id.c
+++ b/lib/smp_processor_id.c
@@ -22,7 +22,7 @@ notrace unsigned int debug_smp_processor_id(void)
* Kernel threads bound to a single CPU can safely use
* smp_processor_id():
*/
- if (cpus_equal(current->cpus_allowed, cpumask_of_cpu(this_cpu)))
+ if (cpumask_equal(&current->cpus_allowed, cpumask_of(this_cpu)))
goto out;
/*
diff --git a/mm/memory.c b/mm/memory.c
index e009ce8..22bfa7a 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -1511,6 +1511,7 @@ int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr,
unsigned long pfn)
{
int ret;
+ pgprot_t pgprot = vma->vm_page_prot;
/*
* Technically, architectures with pte_special can avoid all these
* restrictions (same for remap_pfn_range). However we would like
@@ -1525,10 +1526,10 @@ int vm_insert_pfn(struct vm_area_struct *vma, unsigned long addr,
if (addr < vma->vm_start || addr >= vma->vm_end)
return -EFAULT;
- if (track_pfn_vma_new(vma, vma->vm_page_prot, pfn, PAGE_SIZE))
+ if (track_pfn_vma_new(vma, &pgprot, pfn, PAGE_SIZE))
return -EINVAL;
- ret = insert_pfn(vma, addr, pfn, vma->vm_page_prot);
+ ret = insert_pfn(vma, addr, pfn, pgprot);
if (ret)
untrack_pfn_vma(vma, pfn, PAGE_SIZE);
@@ -1671,9 +1672,15 @@ int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr,
vma->vm_flags |= VM_IO | VM_RESERVED | VM_PFNMAP;
- err = track_pfn_vma_new(vma, prot, pfn, PAGE_ALIGN(size));
- if (err)
+ err = track_pfn_vma_new(vma, &prot, pfn, PAGE_ALIGN(size));
+ if (err) {
+ /*
+ * To indicate that track_pfn related cleanup is not
+ * needed from higher level routine calling unmap_vmas
+ */
+ vma->vm_flags &= ~(VM_IO | VM_RESERVED | VM_PFNMAP);
return -EINVAL;
+ }
BUG_ON(addr >= end);
pfn -= addr >> PAGE_SHIFT;
@@ -3165,6 +3172,15 @@ void print_vma_addr(char *prefix, unsigned long ip)
#ifdef CONFIG_PROVE_LOCKING
void might_fault(void)
{
+ /*
+ * Some code (nfs/sunrpc) uses socket ops on kernel memory while
+ * holding the mmap_sem, this is safe because kernel memory doesn't
+ * get paged out, therefore we'll never actually fault, and the
+ * below annotations will generate false positives.
+ */
+ if (segment_eq(get_fs(), KERNEL_DS))
+ return;
+
might_sleep();
/*
* it would be nicer only to annotate paths which are not under
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index fa108c4..8a8743d 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -85,12 +85,13 @@ static inline int ebt_do_match (struct ebt_entry_match *m,
static inline int ebt_dev_check(char *entry, const struct net_device *device)
{
int i = 0;
- const char *devname = device->name;
+ const char *devname;
if (*entry == '\0')
return 0;
if (!device)
return 1;
+ devname = device->name;
/* 1 is the wildcard token */
while (entry[i] != '\0' && entry[i] != 1 && entry[i] == devname[i])
i++;
diff --git a/net/core/dev.c b/net/core/dev.c
index 5f736f1..b715a55 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1088,6 +1088,11 @@ int dev_open(struct net_device *dev)
dev->flags |= IFF_UP;
/*
+ * Enable NET_DMA
+ */
+ dmaengine_get();
+
+ /*
* Initialize multicasting status
*/
dev_set_rx_mode(dev);
@@ -1164,6 +1169,11 @@ int dev_close(struct net_device *dev)
*/
call_netdevice_notifiers(NETDEV_DOWN, dev);
+ /*
+ * Shutdown NET_DMA
+ */
+ dmaengine_put();
+
return 0;
}
@@ -5151,9 +5161,6 @@ static int __init net_dev_init(void)
hotcpu_notifier(dev_cpu_callback, 0);
dst_init();
dev_mcast_init();
- #ifdef CONFIG_NET_DMA
- dmaengine_get();
- #endif
rc = 0;
out:
return rc;
diff --git a/net/dccp/ccids/Kconfig b/net/dccp/ccids/Kconfig
index b28bf96..4b5db44 100644
--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -29,7 +29,7 @@ config IP_DCCP_CCID3
http://www.ietf.org/rfc/rfc4342.txt
The TFRC congestion control algorithms were initially described in
- RFC 5448.
+ RFC 5348.
This text was extracted from RFC 4340 (sec. 10.2),
http://www.ietf.org/rfc/rfc4340.txt
diff --git a/net/dccp/ccids/lib/tfrc.c b/net/dccp/ccids/lib/tfrc.c
index 60c412c..4902029 100644
--- a/net/dccp/ccids/lib/tfrc.c
+++ b/net/dccp/ccids/lib/tfrc.c
@@ -36,7 +36,7 @@ out:
return rc;
}
-void __exit tfrc_lib_exit(void)
+void tfrc_lib_exit(void)
{
tfrc_rx_packet_history_exit();
tfrc_tx_packet_history_exit();
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index 5aa024b..2f2d731 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -124,7 +124,7 @@ static inline int tipc_nmap_equal(struct tipc_node_map *nm_a, struct tipc_node_m
static inline void tipc_nmap_diff(struct tipc_node_map *nm_a, struct tipc_node_map *nm_b,
struct tipc_node_map *nm_diff)
{
- int stop = sizeof(nm_a->map) / sizeof(u32);
+ int stop = ARRAY_SIZE(nm_a->map);
int w;
int b;
u32 map;
diff --git a/net/xfrm/xfrm_ipcomp.c b/net/xfrm/xfrm_ipcomp.c
index c609a4b..42cd183 100644
--- a/net/xfrm/xfrm_ipcomp.c
+++ b/net/xfrm/xfrm_ipcomp.c
@@ -63,7 +63,6 @@ static int ipcomp_decompress(struct xfrm_state *x, struct sk_buff *skb)
if (len > skb_tailroom(skb))
len = skb_tailroom(skb);
- skb->truesize += len;
__skb_put(skb, len);
len += plen;
diff --git a/scripts/markup_oops.pl b/scripts/markup_oops.pl
index 700a7a6..d40449c 100644
--- a/scripts/markup_oops.pl
+++ b/scripts/markup_oops.pl
@@ -1,5 +1,7 @@
#!/usr/bin/perl -w
+use File::Basename;
+
# Copyright 2008, Intel Corporation
#
# This file is part of the Linux kernel
@@ -13,23 +15,41 @@
my $vmlinux_name = $ARGV[0];
-
+if (!defined($vmlinux_name)) {
+ my $kerver = `uname -r`;
+ chomp($kerver);
+ $vmlinux_name = "/lib/modules/$kerver/build/vmlinux";
+ print "No vmlinux specified, assuming $vmlinux_name\n";
+}
+my $filename = $vmlinux_name;
#
# Step 1: Parse the oops to find the EIP value
#
my $target = "0";
+my $function;
+my $module = "";
+my $func_offset;
+my $vmaoffset = 0;
+
while (<STDIN>) {
- if ($_ =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/) {
+ my $line = $_;
+ if ($line =~ /EIP: 0060:\[\<([a-z0-9]+)\>\]/) {
$target = $1;
}
-}
+ if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]/) {
+ $function = $1;
+ $func_offset = $2;
+ }
-if ($target =~ /^f8/) {
- print "This script does not work on modules ... \n";
- exit;
+ # check if it's a module
+ if ($line =~ /EIP is at ([a-zA-Z0-9\_]+)\+(0x[0-9a-f]+)\/0x[a-f0-9]+\W\[([a-zA-Z0-9\_\-]+)\]/) {
+ $module = $3;
+ }
}
+my $decodestart = hex($target) - hex($func_offset);
+my $decodestop = $decodestart + 8192;
if ($target eq "0") {
print "No oops found!\n";
print "Usage: \n";
@@ -37,6 +57,29 @@ if ($target eq "0") {
exit;
}
+# if it's a module, we need to find the .ko file and calculate a load offset
+if ($module ne "") {
+ my $dir = dirname($filename);
+ $dir = $dir . "/";
+ my $mod = $module . ".ko";
+ my $modulefile = `find $dir -name $mod | head -1`;
+ chomp($modulefile);
+ $filename = $modulefile;
+ if ($filename eq "") {
+ print "Module .ko file for $module not found. Aborting\n";
+ exit;
+ }
+ # ok so we found the module, now we need to calculate the vma offset
+ open(FILE, "objdump -dS $filename |") || die "Cannot start objdump";
+ while (<FILE>) {
+ if ($_ =~ /^([0-9a-f]+) \<$function\>\:/) {
+ my $fu = $1;
+ $vmaoffset = hex($target) - hex($fu) - hex($func_offset);
+ }
+ }
+ close(FILE);
+}
+
my $counter = 0;
my $state = 0;
my $center = 0;
@@ -59,9 +102,7 @@ sub InRange {
# first, parse the input into the lines array, but to keep size down,
# we only do this for 4Kb around the sweet spot
-my $filename;
-
-open(FILE, "objdump -dS $vmlinux_name |") || die "Cannot start objdump";
+open(FILE, "objdump -dS --adjust-vma=$vmaoffset --start-address=$decodestart --stop-address=$decodestop $filename |") || die "Cannot start objdump";
while (<FILE>) {
my $line = $_;
diff --git a/sound/oss/dmasound/dmasound_atari.c b/sound/oss/dmasound/dmasound_atari.c
index 4d45bd6..57d9f15 100644
--- a/sound/oss/dmasound/dmasound_atari.c
+++ b/sound/oss/dmasound/dmasound_atari.c
@@ -851,8 +851,9 @@ static int __init AtaIrqInit(void)
mfp.tim_dt_a = 1; /* Cause interrupt after first event. */
mfp.tim_ct_a = 8; /* Turn on event counting. */
/* Register interrupt handler. */
- request_irq(IRQ_MFP_TIMA, AtaInterrupt, IRQ_TYPE_SLOW, "DMA sound",
- AtaInterrupt);
+ if (request_irq(IRQ_MFP_TIMA, AtaInterrupt, IRQ_TYPE_SLOW, "DMA sound",
+ AtaInterrupt))
+ return 0;
mfp.int_en_a |= 0x20; /* Turn interrupt on. */
mfp.int_mk_a |= 0x20;
return 1;
diff --git a/sound/oss/dmasound/dmasound_q40.c b/sound/oss/dmasound/dmasound_q40.c
index 1855b14..99bcb21 100644
--- a/sound/oss/dmasound/dmasound_q40.c
+++ b/sound/oss/dmasound/dmasound_q40.c
@@ -371,8 +371,9 @@ static void Q40Free(void *ptr, unsigned int size)
static int __init Q40IrqInit(void)
{
/* Register interrupt handler. */
- request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0,
- "DMA sound", Q40Interrupt);
+ if (request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0,
+ "DMA sound", Q40Interrupt))
+ return 0;
return(1);
}
@@ -401,6 +402,7 @@ static void Q40PlayNextFrame(int index)
u_char *start;
u_long size;
u_char speed;
+ int error;
/* used by Q40Play() if all doubts whether there really is something
* to be played are already wiped out.
@@ -419,11 +421,13 @@ static void Q40PlayNextFrame(int index)
master_outb( 0,SAMPLE_ENABLE_REG);
free_irq(Q40_IRQ_SAMPLE, Q40Interrupt);
if (dmasound.soft.stereo)
- request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0,
- "Q40 sound", Q40Interrupt);
+ error = request_irq(Q40_IRQ_SAMPLE, Q40StereoInterrupt, 0,
+ "Q40 sound", Q40Interrupt);
else
- request_irq(Q40_IRQ_SAMPLE, Q40MonoInterrupt, 0,
- "Q40 sound", Q40Interrupt);
+ error = request_irq(Q40_IRQ_SAMPLE, Q40MonoInterrupt, 0,
+ "Q40 sound", Q40Interrupt);
+ if (error && printk_ratelimit())
+ pr_err("Couldn't register sound interrupt\n");
master_outb( speed, SAMPLE_RATE_REG);
master_outb( 1,SAMPLE_CLEAR_REG);
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c
index e00421c..960fd79 100644
--- a/sound/pci/hda/hda_beep.c
+++ b/sound/pci/hda/hda_beep.c
@@ -135,7 +135,6 @@ void snd_hda_detach_beep_device(struct hda_codec *codec)
struct hda_beep *beep = codec->beep;
if (beep) {
cancel_work_sync(&beep->beep_work);
- flush_scheduled_work();
input_unregister_device(beep->dev);
kfree(beep);
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index e16cf63..3c596da 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -373,7 +373,7 @@ int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
unsol->queue[wp] = res;
unsol->queue[wp + 1] = res_ex;
- schedule_work(&unsol->work);
+ queue_work(bus->workq, &unsol->work);
return 0;
}
@@ -437,15 +437,17 @@ static int snd_hda_bus_free(struct hda_bus *bus)
if (!bus)
return 0;
- if (bus->unsol) {
- flush_scheduled_work();
+ if (bus->workq)
+ flush_workqueue(bus->workq);
+ if (bus->unsol)
kfree(bus->unsol);
- }
list_for_each_entry_safe(codec, n, &bus->codec_list, list) {
snd_hda_codec_free(codec);
}
if (bus->ops.private_free)
bus->ops.private_free(bus);
+ if (bus->workq)
+ destroy_workqueue(bus->workq);
kfree(bus);
return 0;
}
@@ -485,6 +487,7 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card,
{
struct hda_bus *bus;
int err;
+ char qname[8];
static struct snd_device_ops dev_ops = {
.dev_register = snd_hda_bus_dev_register,
.dev_free = snd_hda_bus_dev_free,
@@ -514,6 +517,14 @@ int /*__devinit*/ snd_hda_bus_new(struct snd_card *card,
mutex_init(&bus->cmd_mutex);
INIT_LIST_HEAD(&bus->codec_list);
+ snprintf(qname, sizeof(qname), "hda%d", card->number);
+ bus->workq = create_workqueue(qname);
+ if (!bus->workq) {
+ snd_printk(KERN_ERR "cannot create workqueue %s\n", qname);
+ kfree(bus);
+ return -ENOMEM;
+ }
+
err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops);
if (err < 0) {
snd_hda_bus_free(bus);
@@ -684,7 +695,7 @@ static void snd_hda_codec_free(struct hda_codec *codec)
return;
#ifdef CONFIG_SND_HDA_POWER_SAVE
cancel_delayed_work(&codec->power_work);
- flush_scheduled_work();
+ flush_workqueue(codec->bus->workq);
#endif
list_del(&codec->list);
snd_array_free(&codec->mixers);
@@ -735,6 +746,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr
codec->bus = bus;
codec->addr = codec_addr;
mutex_init(&codec->spdif_mutex);
+ mutex_init(&codec->control_mutex);
init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
snd_array_init(&codec->mixers, sizeof(struct snd_kcontrol *), 32);
@@ -1272,7 +1284,7 @@ void snd_hda_codec_reset(struct hda_codec *codec)
#ifdef CONFIG_SND_HDA_POWER_SAVE
cancel_delayed_work(&codec->power_work);
- flush_scheduled_work();
+ flush_workqueue(codec->bus->workq);
#endif
snd_hda_ctls_clear(codec);
/* relase PCMs */
@@ -1418,12 +1430,12 @@ int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
unsigned long pval;
int err;
- mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ mutex_lock(&codec->control_mutex);
pval = kcontrol->private_value;
kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
kcontrol->private_value = pval;
- mutex_unlock(&codec->spdif_mutex);
+ mutex_unlock(&codec->control_mutex);
return err;
}
EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_get);
@@ -1435,7 +1447,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
unsigned long pval;
int i, indices, err = 0, change = 0;
- mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ mutex_lock(&codec->control_mutex);
pval = kcontrol->private_value;
indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
for (i = 0; i < indices; i++) {
@@ -1447,7 +1459,7 @@ int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
change |= err;
}
kcontrol->private_value = pval;
- mutex_unlock(&codec->spdif_mutex);
+ mutex_unlock(&codec->control_mutex);
return err < 0 ? err : change;
}
EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_put);
@@ -1462,12 +1474,12 @@ int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
struct hda_bind_ctls *c;
int err;
- mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ mutex_lock(&codec->control_mutex);
c = (struct hda_bind_ctls *)kcontrol->private_value;
kcontrol->private_value = *c->values;
err = c->ops->info(kcontrol, uinfo);
kcontrol->private_value = (long)c;
- mutex_unlock(&codec->spdif_mutex);
+ mutex_unlock(&codec->control_mutex);
return err;
}
EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_info);
@@ -1479,12 +1491,12 @@ int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
struct hda_bind_ctls *c;
int err;
- mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ mutex_lock(&codec->control_mutex);
c = (struct hda_bind_ctls *)kcontrol->private_value;
kcontrol->private_value = *c->values;
err = c->ops->get(kcontrol, ucontrol);
kcontrol->private_value = (long)c;
- mutex_unlock(&codec->spdif_mutex);
+ mutex_unlock(&codec->control_mutex);
return err;
}
EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_get);
@@ -1497,7 +1509,7 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
unsigned long *vals;
int err = 0, change = 0;
- mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ mutex_lock(&codec->control_mutex);
c = (struct hda_bind_ctls *)kcontrol->private_value;
for (vals = c->values; *vals; vals++) {
kcontrol->private_value = *vals;
@@ -1507,7 +1519,7 @@ int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
change |= err;
}
kcontrol->private_value = (long)c;
- mutex_unlock(&codec->spdif_mutex);
+ mutex_unlock(&codec->control_mutex);
return err < 0 ? err : change;
}
EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_put);
@@ -1519,12 +1531,12 @@ int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
struct hda_bind_ctls *c;
int err;
- mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ mutex_lock(&codec->control_mutex);
c = (struct hda_bind_ctls *)kcontrol->private_value;
kcontrol->private_value = *c->values;
err = c->ops->tlv(kcontrol, op_flag, size, tlv);
kcontrol->private_value = (long)c;
- mutex_unlock(&codec->spdif_mutex);
+ mutex_unlock(&codec->control_mutex);
return err;
}
EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_tlv);
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 729fc76..5810ef5 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -614,6 +614,7 @@ struct hda_bus {
/* unsolicited event queue */
struct hda_bus_unsolicited *unsol;
+ struct workqueue_struct *workq; /* common workqueue for codecs */
/* assigned PCMs */
DECLARE_BITMAP(pcm_dev_bits, SNDRV_PCM_DEVICES);
@@ -771,6 +772,7 @@ struct hda_codec {
struct hda_cache_rec cmd_cache; /* cache for other commands */
struct mutex spdif_mutex;
+ struct mutex control_mutex;
unsigned int spdif_status; /* IEC958 status bits */
unsigned short spdif_ctls; /* SPDIF control bits */
unsigned int spdif_in_enable; /* SPDIF input enable? */
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index f04de11..11e791b 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -996,10 +996,11 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
spin_unlock(&chip->reg_lock);
snd_pcm_period_elapsed(azx_dev->substream);
spin_lock(&chip->reg_lock);
- } else {
+ } else if (chip->bus && chip->bus->workq) {
/* bogus IRQ, process it later */
azx_dev->irq_pending = 1;
- schedule_work(&chip->irq_pending_work);
+ queue_work(chip->bus->workq,
+ &chip->irq_pending_work);
}
}
}
@@ -1741,7 +1742,6 @@ static void azx_clear_irq_pending(struct azx *chip)
for (i = 0; i < chip->num_streams; i++)
chip->azx_dev[i].irq_pending = 0;
spin_unlock_irq(&chip->reg_lock);
- flush_scheduled_work();
}
static struct snd_pcm_ops azx_pcm_ops = {
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index 26247cf..2e7371e 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -3900,6 +3900,7 @@ static const char *ad1884a_models[AD1884A_MODELS] = {
static struct snd_pci_quirk ad1884a_cfg_tbl[] = {
SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
+ SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP),
SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
SND_PCI_QUIRK(0x103c, 0x30e6, "HP 6730b", AD1884A_LAPTOP),
SND_PCI_QUIRK(0x103c, 0x30e7, "HP EliteBook 8530p", AD1884A_LAPTOP),
@@ -4262,13 +4263,13 @@ static int patch_ad1882(struct hda_codec *codec)
spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
spec->adc_nids = ad1882_adc_nids;
spec->capsrc_nids = ad1882_capsrc_nids;
- if (codec->vendor_id == 0x11d1882)
+ if (codec->vendor_id == 0x11d41882)
spec->input_mux = &ad1882_capture_source;
else
spec->input_mux = &ad1882a_capture_source;
spec->num_mixers = 2;
spec->mixers[0] = ad1882_base_mixers;
- if (codec->vendor_id == 0x11d1882)
+ if (codec->vendor_id == 0x11d41882)
spec->mixers[1] = ad1882_loopback_mixers;
else
spec->mixers[1] = ad1882a_loopback_mixers;
diff --git a/sound/pci/hda/patch_nvhdmi.c b/sound/pci/hda/patch_nvhdmi.c
index 0270fda..96952a3 100644
--- a/sound/pci/hda/patch_nvhdmi.c
+++ b/sound/pci/hda/patch_nvhdmi.c
@@ -162,12 +162,14 @@ static struct hda_codec_preset snd_hda_preset_nvhdmi[] = {
{ .id = 0x10de0002, .name = "MCP78 HDMI", .patch = patch_nvhdmi },
{ .id = 0x10de0007, .name = "MCP7A HDMI", .patch = patch_nvhdmi },
{ .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi },
+ { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi },
{} /* terminator */
};
MODULE_ALIAS("snd-hda-codec-id:10de0002");
MODULE_ALIAS("snd-hda-codec-id:10de0007");
MODULE_ALIAS("snd-hda-codec-id:10de0067");
+MODULE_ALIAS("snd-hda-codec-id:10de8001");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Nvidia HDMI HD-audio codec");
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 9065ebf..ea4c88f 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1502,11 +1502,11 @@ static int alc_cap_vol_info(struct snd_kcontrol *kcontrol,
struct alc_spec *spec = codec->spec;
int err;
- mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ mutex_lock(&codec->control_mutex);
kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
HDA_INPUT);
err = snd_hda_mixer_amp_volume_info(kcontrol, uinfo);
- mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ mutex_unlock(&codec->control_mutex);
return err;
}
@@ -1517,11 +1517,11 @@ static int alc_cap_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag,
struct alc_spec *spec = codec->spec;
int err;
- mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ mutex_lock(&codec->control_mutex);
kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[0], 3, 0,
HDA_INPUT);
err = snd_hda_mixer_amp_tlv(kcontrol, op_flag, size, tlv);
- mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ mutex_unlock(&codec->control_mutex);
return err;
}
@@ -1537,11 +1537,11 @@ static int alc_cap_getput_caller(struct snd_kcontrol *kcontrol,
unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
int err;
- mutex_lock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ mutex_lock(&codec->control_mutex);
kcontrol->private_value = HDA_COMPOSE_AMP_VAL(spec->adc_nids[adc_idx],
3, 0, HDA_INPUT);
err = func(kcontrol, ucontrol);
- mutex_unlock(&codec->spdif_mutex); /* reuse spdif_mutex */
+ mutex_unlock(&codec->control_mutex);
return err;
}
@@ -8461,6 +8461,10 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x0121, "Acer Aspire 5920G", ALC883_ACER_ASPIRE),
SND_PCI_QUIRK(0x1025, 0x013e, "Acer Aspire 4930G",
ALC888_ACER_ASPIRE_4930G),
+ SND_PCI_QUIRK(0x1025, 0x013f, "Acer Aspire 5930G",
+ ALC888_ACER_ASPIRE_4930G),
+ SND_PCI_QUIRK(0x1025, 0x015e, "Acer Aspire 6930G",
+ ALC888_ACER_ASPIRE_4930G),
SND_PCI_QUIRK(0x1025, 0, "Acer laptop", ALC883_ACER), /* default Acer */
SND_PCI_QUIRK(0x1028, 0x020d, "Dell Inspiron 530", ALC888_6ST_DELL),
SND_PCI_QUIRK(0x103c, 0x2a3d, "HP Pavillion", ALC883_6ST_DIG),
@@ -8522,6 +8526,7 @@ static struct snd_pci_quirk alc883_cfg_tbl[] = {
SND_PCI_QUIRK(0x1991, 0x5625, "Haier W66", ALC883_HAIER_W66),
SND_PCI_QUIRK(0x8086, 0x0001, "DG33BUC", ALC883_3ST_6ch_INTEL),
SND_PCI_QUIRK(0x8086, 0x0002, "DG33FBC", ALC883_3ST_6ch_INTEL),
+ SND_PCI_QUIRK(0x8086, 0x0022, "DX58SO", ALC883_3ST_6ch_INTEL),
SND_PCI_QUIRK(0x8086, 0xd601, "D102GGC", ALC883_3ST_6ch),
{}
};
@@ -11689,6 +11694,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = {
SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One",
ALC268_ACER_ASPIRE_ONE),
SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL),
+ SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron Mini9", ALC268_DELL),
SND_PCI_QUIRK(0x103c, 0x30cc, "TOSHIBA", ALC268_TOSHIBA),
SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC268_3ST),
SND_PCI_QUIRK(0x1179, 0xff10, "TOSHIBA A205", ALC268_TOSHIBA),
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c
index fd0f338..ea370a4 100644
--- a/sound/soc/codecs/twl4030.c
+++ b/sound/soc/codecs/twl4030.c
@@ -197,7 +197,7 @@ static const char *twl4030_earpiece_texts[] =
static const unsigned int twl4030_earpiece_values[] =
{0x0, 0x1, 0x2, 0x4};
-static const struct soc_value_enum twl4030_earpiece_enum =
+static const struct soc_enum twl4030_earpiece_enum =
SOC_VALUE_ENUM_SINGLE(TWL4030_REG_EAR_CTL, 1, 0x7,
ARRAY_SIZE(twl4030_earpiece_texts),
twl4030_earpiece_texts,
@@ -213,7 +213,7 @@ static const char *twl4030_predrivel_texts[] =
static const unsigned int twl4030_predrivel_values[] =
{0x0, 0x1, 0x2, 0x4};
-static const struct soc_value_enum twl4030_predrivel_enum =
+static const struct soc_enum twl4030_predrivel_enum =
SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDL_CTL, 1, 0x7,
ARRAY_SIZE(twl4030_predrivel_texts),
twl4030_predrivel_texts,
@@ -229,7 +229,7 @@ static const char *twl4030_predriver_texts[] =
static const unsigned int twl4030_predriver_values[] =
{0x0, 0x1, 0x2, 0x4};
-static const struct soc_value_enum twl4030_predriver_enum =
+static const struct soc_enum twl4030_predriver_enum =
SOC_VALUE_ENUM_SINGLE(TWL4030_REG_PREDR_CTL, 1, 0x7,
ARRAY_SIZE(twl4030_predriver_texts),
twl4030_predriver_texts,
@@ -317,7 +317,7 @@ static const char *twl4030_analoglmic_texts[] =
static const unsigned int twl4030_analoglmic_values[] =
{0x0, 0x1, 0x2, 0x4, 0x8};
-static const struct soc_value_enum twl4030_analoglmic_enum =
+static const struct soc_enum twl4030_analoglmic_enum =
SOC_VALUE_ENUM_SINGLE(TWL4030_REG_ANAMICL, 0, 0xf,
ARRAY_SIZE(twl4030_analoglmic_texts),
twl4030_analoglmic_texts,
@@ -333,7 +333,7 @@ static const char *twl4030_analogrmic_texts[] =
static const unsigned int twl4030_analogrmic_values[] =
{0x0, 0x1, 0x4};
-static const struct soc_value_enum twl4030_analogrmic_enum =
+static const struct soc_enum twl4030_analogrmic_enum =
SOC_VALUE_ENUM_SINGLE(TWL4030_REG_ANAMICR, 0, 0x5,
ARRAY_SIZE(twl4030_analogrmic_texts),
twl4030_analogrmic_texts,
@@ -1280,6 +1280,8 @@ static int twl4030_remove(struct platform_device *pdev)
struct snd_soc_codec *codec = socdev->codec;
printk(KERN_INFO "TWL4030 Audio Codec remove\n");
+ snd_soc_free_pcms(socdev);
+ snd_soc_dapm_free(socdev);
kfree(codec);
return 0;
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 6cbe7e8..55fdb4a 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -1585,37 +1585,6 @@ int snd_soc_put_enum_double(struct snd_kcontrol *kcontrol,
EXPORT_SYMBOL_GPL(snd_soc_put_enum_double);
/**
- * snd_soc_info_value_enum_double - semi enumerated double mixer info callback
- * @kcontrol: mixer control
- * @uinfo: control element information
- *
- * Callback to provide information about a double semi enumerated
- * mixer control.
- *
- * Semi enumerated mixer: the enumerated items are referred as values. Can be
- * used for handling bitfield coded enumeration for example.
- *
- * Returns 0 for success.
- */
-int snd_soc_info_value_enum_double(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_info *uinfo)
-{
- struct soc_value_enum *e = (struct soc_value_enum *)
- kcontrol->private_value;
-
- uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
- uinfo->count = e->shift_l == e->shift_r ? 1 : 2;
- uinfo->value.enumerated.items = e->max;
-
- if (uinfo->value.enumerated.item > e->max - 1)
- uinfo->value.enumerated.item = e->max - 1;
- strcpy(uinfo->value.enumerated.name,
- e->texts[uinfo->value.enumerated.item]);
- return 0;
-}
-EXPORT_SYMBOL_GPL(snd_soc_info_value_enum_double);
-
-/**
* snd_soc_get_value_enum_double - semi enumerated double mixer get callback
* @kcontrol: mixer control
* @ucontrol: control element information
@@ -1631,8 +1600,7 @@ int snd_soc_get_value_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct soc_value_enum *e = (struct soc_value_enum *)
- kcontrol->private_value;
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned short reg_val, val, mux;
reg_val = snd_soc_read(codec, e->reg);
@@ -1671,8 +1639,7 @@ int snd_soc_put_value_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
- struct soc_value_enum *e = (struct soc_value_enum *)
- kcontrol->private_value;
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned short val;
unsigned short mask;
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index ad0d801..493a4e8 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -137,7 +137,7 @@ static void dapm_set_path_status(struct snd_soc_dapm_widget *w,
}
break;
case snd_soc_dapm_value_mux: {
- struct soc_value_enum *e = (struct soc_value_enum *)
+ struct soc_enum *e = (struct soc_enum *)
w->kcontrols[i].private_value;
int val, item;
@@ -200,30 +200,6 @@ static int dapm_connect_mux(struct snd_soc_codec *codec,
return -ENODEV;
}
-/* connect value_mux widget to it's interconnecting audio paths */
-static int dapm_connect_value_mux(struct snd_soc_codec *codec,
- struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
- struct snd_soc_dapm_path *path, const char *control_name,
- const struct snd_kcontrol_new *kcontrol)
-{
- struct soc_value_enum *e = (struct soc_value_enum *)
- kcontrol->private_value;
- int i;
-
- for (i = 0; i < e->max; i++) {
- if (!(strcmp(control_name, e->texts[i]))) {
- list_add(&path->list, &codec->dapm_paths);
- list_add(&path->list_sink, &dest->sources);
- list_add(&path->list_source, &src->sinks);
- path->name = (char *)e->texts[i];
- dapm_set_path_status(dest, path, 0);
- return 0;
- }
- }
-
- return -ENODEV;
-}
-
/* connect mixer widget to it's interconnecting audio paths */
static int dapm_connect_mixer(struct snd_soc_codec *codec,
struct snd_soc_dapm_widget *src, struct snd_soc_dapm_widget *dest,
@@ -774,45 +750,6 @@ static int dapm_mux_update_power(struct snd_soc_dapm_widget *widget,
return 0;
}
-/* test and update the power status of a value_mux widget */
-static int dapm_value_mux_update_power(struct snd_soc_dapm_widget *widget,
- struct snd_kcontrol *kcontrol, int mask,
- int mux, int val, struct soc_value_enum *e)
-{
- struct snd_soc_dapm_path *path;
- int found = 0;
-
- if (widget->id != snd_soc_dapm_value_mux)
- return -ENODEV;
-
- if (!snd_soc_test_bits(widget->codec, e->reg, mask, val))
- return 0;
-
- /* find dapm widget path assoc with kcontrol */
- list_for_each_entry(path, &widget->codec->dapm_paths, list) {
- if (path->kcontrol != kcontrol)
- continue;
-
- if (!path->name || !e->texts[mux])
- continue;
-
- found = 1;
- /* we now need to match the string in the enum to the path */
- if (!(strcmp(path->name, e->texts[mux])))
- path->connect = 1; /* new connection */
- else
- path->connect = 0; /* old connection must be
- powered down */
- }
-
- if (found) {
- dapm_power_widgets(widget->codec, SND_SOC_DAPM_STREAM_NOP);
- dump_dapm(widget->codec, "mux power update");
- }
-
- return 0;
-}
-
/* test and update the power status of a mixer or switch widget */
static int dapm_mixer_update_power(struct snd_soc_dapm_widget *widget,
struct snd_kcontrol *kcontrol, int reg,
@@ -1045,17 +982,12 @@ static int snd_soc_dapm_add_route(struct snd_soc_codec *codec,
path->connect = 1;
return 0;
case snd_soc_dapm_mux:
+ case snd_soc_dapm_value_mux:
ret = dapm_connect_mux(codec, wsource, wsink, path, control,
&wsink->kcontrols[0]);
if (ret != 0)
goto err;
break;
- case snd_soc_dapm_value_mux:
- ret = dapm_connect_value_mux(codec, wsource, wsink, path,
- control, &wsink->kcontrols[0]);
- if (ret != 0)
- goto err;
- break;
case snd_soc_dapm_switch:
case snd_soc_dapm_mixer:
ret = dapm_connect_mixer(codec, wsource, wsink, path, control);
@@ -1382,8 +1314,7 @@ int snd_soc_dapm_get_value_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
- struct soc_value_enum *e = (struct soc_value_enum *)
- kcontrol->private_value;
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned short reg_val, val, mux;
reg_val = snd_soc_read(widget->codec, e->reg);
@@ -1423,8 +1354,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol);
- struct soc_value_enum *e = (struct soc_value_enum *)
- kcontrol->private_value;
+ struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
unsigned short val, mux;
unsigned short mask;
int ret = 0;
@@ -1443,7 +1373,7 @@ int snd_soc_dapm_put_value_enum_double(struct snd_kcontrol *kcontrol,
mutex_lock(&widget->codec->mutex);
widget->value = val;
- dapm_value_mux_update_power(widget, kcontrol, mask, mux, val, e);
+ dapm_mux_update_power(widget, kcontrol, mask, mux, val, e);
if (widget->event) {
if (widget->event_flags & SND_SOC_DAPM_PRE_REG) {
ret = widget->event(widget,
diff --git a/sound/usb/caiaq/caiaq-device.c b/sound/usb/caiaq/caiaq-device.c
index a62500e..41c36b0 100644
--- a/sound/usb/caiaq/caiaq-device.c
+++ b/sound/usb/caiaq/caiaq-device.c
@@ -42,7 +42,7 @@
#endif
MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>");
-MODULE_DESCRIPTION("caiaq USB audio, version 1.3.9");
+MODULE_DESCRIPTION("caiaq USB audio, version 1.3.10");
MODULE_LICENSE("GPL");
MODULE_SUPPORTED_DEVICE("{{Native Instruments, RigKontrol2},"
"{Native Instruments, RigKontrol3},"
diff --git a/sound/usb/caiaq/caiaq-device.h b/sound/usb/caiaq/caiaq-device.h
index f9fbdba..ab56e73 100644
--- a/sound/usb/caiaq/caiaq-device.h
+++ b/sound/usb/caiaq/caiaq-device.h
@@ -75,6 +75,7 @@ struct snd_usb_caiaqdev {
wait_queue_head_t ep1_wait_queue;
wait_queue_head_t prepare_wait_queue;
int spec_received, audio_parm_answer;
+ int midi_out_active;
char vendor_name[CAIAQ_USB_STR_LEN];
char product_name[CAIAQ_USB_STR_LEN];
diff --git a/sound/usb/caiaq/caiaq-midi.c b/sound/usb/caiaq/caiaq-midi.c
index 30b57f9..f19fd36 100644
--- a/sound/usb/caiaq/caiaq-midi.c
+++ b/sound/usb/caiaq/caiaq-midi.c
@@ -59,6 +59,11 @@ static int snd_usb_caiaq_midi_output_open(struct snd_rawmidi_substream *substrea
static int snd_usb_caiaq_midi_output_close(struct snd_rawmidi_substream *substream)
{
+ struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;
+ if (dev->midi_out_active) {
+ usb_kill_urb(&dev->midi_out_urb);
+ dev->midi_out_active = 0;
+ }
return 0;
}
@@ -69,7 +74,8 @@ static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *dev,
dev->midi_out_buf[0] = EP1_CMD_MIDI_WRITE;
dev->midi_out_buf[1] = 0; /* port */
- len = snd_rawmidi_transmit_peek(substream, dev->midi_out_buf+3, EP1_BUFSIZE-3);
+ len = snd_rawmidi_transmit(substream, dev->midi_out_buf + 3,
+ EP1_BUFSIZE - 3);
if (len <= 0)
return;
@@ -79,24 +85,24 @@ static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *dev,
ret = usb_submit_urb(&dev->midi_out_urb, GFP_ATOMIC);
if (ret < 0)
- log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed, %d\n",
- substream, ret);
+ log("snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed,"
+ "ret=%d, len=%d\n",
+ substream, ret, len);
+ else
+ dev->midi_out_active = 1;
}
static void snd_usb_caiaq_midi_output_trigger(struct snd_rawmidi_substream *substream, int up)
{
struct snd_usb_caiaqdev *dev = substream->rmidi->private_data;
- if (dev->midi_out_substream != NULL)
- return;
-
- if (!up) {
+ if (up) {
+ dev->midi_out_substream = substream;
+ if (!dev->midi_out_active)
+ snd_usb_caiaq_midi_send(dev, substream);
+ } else {
dev->midi_out_substream = NULL;
- return;
}
-
- dev->midi_out_substream = substream;
- snd_usb_caiaq_midi_send(dev, substream);
}
@@ -161,16 +167,14 @@ int snd_usb_caiaq_midi_init(struct snd_usb_caiaqdev *device)
void snd_usb_caiaq_midi_output_done(struct urb* urb)
{
struct snd_usb_caiaqdev *dev = urb->context;
- char *buf = urb->transfer_buffer;
+ dev->midi_out_active = 0;
if (urb->status != 0)
return;
if (!dev->midi_out_substream)
return;
- snd_rawmidi_transmit_ack(dev->midi_out_substream, buf[2]);
- dev->midi_out_substream = NULL;
snd_usb_caiaq_midi_send(dev, dev->midi_out_substream);
}