summaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/Kconfig7
-rw-r--r--arch/alpha/Kconfig1
-rw-r--r--arch/alpha/include/asm/unistd.h1
-rw-r--r--arch/alpha/kernel/smc37c669.c12
-rw-r--r--arch/arm/Kconfig3
-rw-r--r--arch/arm/boot/dts/highbank.dts12
-rw-r--r--arch/arm/boot/dts/imx28.dtsi2
-rw-r--r--arch/arm/boot/dts/r8a7740.dtsi21
-rw-r--r--arch/arm/boot/dts/sh7377.dtsi21
-rw-r--r--arch/arm/boot/dts/tegra20.dtsi6
-rw-r--r--arch/arm/boot/dts/tegra30.dtsi6
-rw-r--r--arch/arm/common/dmabounce.c1
-rw-r--r--arch/arm/configs/armadillo800eva_defconfig25
-rw-r--r--arch/arm/configs/kzm9d_defconfig89
-rw-r--r--arch/arm/configs/kzm9g_defconfig8
-rw-r--r--arch/arm/configs/omap2plus_defconfig2
-rw-r--r--arch/arm/configs/tegra_defconfig1
-rw-r--r--arch/arm/include/asm/cacheflush.h8
-rw-r--r--arch/arm/include/asm/dma-mapping.h24
-rw-r--r--arch/arm/include/asm/mutex.h119
-rw-r--r--arch/arm/include/asm/setup.h4
-rw-r--r--arch/arm/include/asm/unistd.h1
-rw-r--r--arch/arm/kernel/entry-armv.S111
-rw-r--r--arch/arm/kernel/entry-common.S24
-rw-r--r--arch/arm/kernel/ftrace.c17
-rw-r--r--arch/arm/kernel/process.c2
-rw-r--r--arch/arm/kernel/ptrace.c1
-rw-r--r--arch/arm/kernel/setup.c6
-rw-r--r--arch/arm/kernel/signal.c114
-rw-r--r--arch/arm/kernel/signal.h2
-rw-r--r--arch/arm/kernel/smp.c3
-rw-r--r--arch/arm/kernel/traps.c10
-rw-r--r--arch/arm/lib/io-acorn.S3
-rw-r--r--arch/arm/mach-davinci/devices-da8xx.c1
-rw-r--r--arch/arm/mach-exynos/clock-exynos4.c41
-rw-r--r--arch/arm/mach-exynos/clock-exynos4.h3
-rw-r--r--arch/arm/mach-exynos/clock-exynos4210.c37
-rw-r--r--arch/arm/mach-exynos/clock-exynos4212.c41
-rw-r--r--arch/arm/mach-exynos/mach-nuri.c4
-rw-r--r--arch/arm/mach-exynos/mach-origen.c1
-rw-r--r--arch/arm/mach-netx/fb.c23
-rw-r--r--arch/arm/mach-omap1/board-h2-mmc.c1
-rw-r--r--arch/arm/mach-omap1/board-h3-mmc.c1
-rw-r--r--arch/arm/mach-omap1/board-nokia770.c1
-rw-r--r--arch/arm/mach-omap1/board-palmz71.c3
-rw-r--r--arch/arm/mach-omap2/board-n8x0.c1
-rw-r--r--arch/arm/mach-omap2/display.c25
-rw-r--r--arch/arm/mach-omap2/hsmmc.c1
-rw-r--r--arch/arm/mach-pxa/eseries.h14
-rw-r--r--arch/arm/mach-pxa/hx4700.c56
-rw-r--r--arch/arm/mach-pxa/lubbock.c2
-rw-r--r--arch/arm/mach-pxa/magician.c5
-rw-r--r--arch/arm/mach-pxa/trizeps4.c4
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/pm-core.h4
-rw-r--r--arch/arm/mach-shmobile/Kconfig13
-rw-r--r--arch/arm/mach-shmobile/Makefile2
-rw-r--r--arch/arm/mach-shmobile/board-ag5evm.c82
-rw-r--r--arch/arm/mach-shmobile/board-ap4evb.c62
-rw-r--r--arch/arm/mach-shmobile/board-armadillo800eva.c455
-rw-r--r--arch/arm/mach-shmobile/board-bonito.c10
-rw-r--r--arch/arm/mach-shmobile/board-g4evm.c52
-rw-r--r--arch/arm/mach-shmobile/board-kota2.c30
-rw-r--r--arch/arm/mach-shmobile/board-kzm9d.c10
-rw-r--r--arch/arm/mach-shmobile/board-kzm9g.c320
-rw-r--r--arch/arm/mach-shmobile/board-mackerel.c83
-rw-r--r--arch/arm/mach-shmobile/board-marzen.c10
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7740.c150
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7779.c2
-rw-r--r--arch/arm/mach-shmobile/clock-sh7367.c2
-rw-r--r--arch/arm/mach-shmobile/clock-sh7372.c2
-rw-r--r--arch/arm/mach-shmobile/clock-sh7377.c2
-rw-r--r--arch/arm/mach-shmobile/clock-sh73a0.c12
-rw-r--r--arch/arm/mach-shmobile/include/mach/common.h1
-rw-r--r--arch/arm/mach-shmobile/include/mach/dma-register.h84
-rw-r--r--arch/arm/mach-shmobile/include/mach/gpio.h32
-rw-r--r--arch/arm/mach-shmobile/include/mach/pm-rmobile.h44
-rw-r--r--arch/arm/mach-shmobile/include/mach/r8a7740.h33
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh7372.h45
-rw-r--r--arch/arm/mach-shmobile/include/mach/sh73a0.h7
-rw-r--r--arch/arm/mach-shmobile/intc-r8a7740.c13
-rw-r--r--arch/arm/mach-shmobile/pfc-r8a7740.c24
-rw-r--r--arch/arm/mach-shmobile/pm-r8a7740.c54
-rw-r--r--arch/arm/mach-shmobile/pm-rmobile.c167
-rw-r--r--arch/arm/mach-shmobile/pm-sh7372.c297
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7740.c360
-rw-r--r--arch/arm/mach-shmobile/setup-sh7372.c209
-rw-r--r--arch/arm/mach-shmobile/setup-sh7377.c47
-rw-r--r--arch/arm/mach-shmobile/setup-sh73a0.c152
-rw-r--r--arch/arm/mach-spear3xx/spear300.c26
-rw-r--r--arch/arm/mach-spear3xx/spear310.c26
-rw-r--r--arch/arm/mach-spear3xx/spear320.c26
-rw-r--r--arch/arm/mach-spear3xx/spear3xx.c3
-rw-r--r--arch/arm/mach-spear6xx/spear6xx.c51
-rw-r--r--arch/arm/mach-tegra/board-dt-tegra20.c3
-rw-r--r--arch/arm/mach-tegra/board-dt-tegra30.c3
-rw-r--r--arch/arm/mach-ux500/board-mop500.c32
-rw-r--r--arch/arm/mach-ux500/cpu-db8500.c7
-rw-r--r--arch/arm/mach-ux500/devices-common.h24
-rw-r--r--arch/arm/mach-ux500/include/mach/setup.h3
-rw-r--r--arch/arm/mach-vt8500/Makefile2
-rw-r--r--arch/arm/mach-vt8500/pwm.c265
-rw-r--r--arch/arm/mm/dma-mapping.c561
-rw-r--r--arch/arm/mm/mm.h3
-rw-r--r--arch/arm/mm/tlb-v7.S12
-rw-r--r--arch/arm/plat-mxc/Kconfig6
-rw-r--r--arch/arm/plat-mxc/Makefile1
-rw-r--r--arch/arm/plat-mxc/include/mach/i2c.h2
-rw-r--r--arch/arm/plat-mxc/pwm.c306
-rw-r--r--arch/arm/plat-nomadik/include/plat/i2c.h39
-rw-r--r--arch/arm/plat-omap/include/plat/mmc.h2
-rw-r--r--arch/arm/plat-pxa/Makefile1
-rw-r--r--arch/arm/plat-pxa/pwm.c304
-rw-r--r--arch/arm/plat-samsung/Makefile4
-rw-r--r--arch/arm/plat-samsung/pwm.c416
-rw-r--r--arch/arm/plat-spear/include/plat/pl080.h6
-rw-r--r--arch/arm/plat-spear/pl080.c10
-rw-r--r--arch/arm/vfp/entry.S16
-rw-r--r--arch/arm/vfp/vfphw.S26
-rw-r--r--arch/arm/vfp/vfpmodule.c8
-rw-r--r--arch/avr32/Kconfig1
-rw-r--r--arch/avr32/boards/atstk1000/atstk1002.c2
-rw-r--r--arch/avr32/include/asm/unistd.h1
-rw-r--r--arch/avr32/mm/fault.c33
-rw-r--r--arch/blackfin/Kconfig11
-rw-r--r--arch/blackfin/include/asm/unistd.h1
-rw-r--r--arch/blackfin/kernel/Makefile1
-rw-r--r--arch/blackfin/kernel/pwm.c100
-rw-r--r--arch/cris/Kconfig1
-rw-r--r--arch/cris/include/asm/unistd.h1
-rw-r--r--arch/frv/Kconfig1
-rw-r--r--arch/frv/include/asm/cpumask.h6
-rw-r--r--arch/frv/include/asm/unistd.h1
-rw-r--r--arch/frv/kernel/kernel_thread.S2
-rw-r--r--arch/h8300/Kconfig1
-rw-r--r--arch/h8300/include/asm/unistd.h1
-rw-r--r--arch/hexagon/include/asm/Kbuild2
-rw-r--r--arch/ia64/Kconfig3
-rw-r--r--arch/ia64/include/asm/atomic.h4
-rw-r--r--arch/ia64/include/asm/machvec.h2
-rw-r--r--arch/ia64/include/asm/machvec_dig.h2
-rw-r--r--arch/ia64/include/asm/machvec_dig_vtd.h2
-rw-r--r--arch/ia64/include/asm/machvec_hpsim.h2
-rw-r--r--arch/ia64/include/asm/machvec_hpzx1.h2
-rw-r--r--arch/ia64/include/asm/machvec_hpzx1_swiotlb.h2
-rw-r--r--arch/ia64/include/asm/machvec_sn2.h2
-rw-r--r--arch/ia64/include/asm/machvec_uv.h2
-rw-r--r--arch/ia64/include/asm/machvec_xen.h2
-rw-r--r--arch/ia64/include/asm/processor.h2
-rw-r--r--arch/ia64/kernel/irq_ia64.c1
-rw-r--r--arch/ia64/kernel/perfmon.c1
-rw-r--r--arch/ia64/kvm/Kconfig1
-rw-r--r--arch/ia64/pci/fixup.c4
-rw-r--r--arch/m32r/Kconfig1
-rw-r--r--arch/m32r/include/asm/unistd.h1
-rw-r--r--arch/m68k/Kconfig1
-rw-r--r--arch/m68k/include/asm/unistd.h1
-rw-r--r--arch/microblaze/Kconfig1
-rw-r--r--arch/microblaze/include/asm/unistd.h1
-rw-r--r--arch/mips/Kbuild.platforms1
-rw-r--r--arch/mips/Kconfig42
-rw-r--r--arch/mips/alchemy/board-mtx1.c4
-rw-r--r--arch/mips/alchemy/common/platform.c10
-rw-r--r--arch/mips/alchemy/devboards/Makefile2
-rw-r--r--arch/mips/alchemy/devboards/bcsr.c5
-rw-r--r--arch/mips/alchemy/devboards/pb1100.c4
-rw-r--r--arch/mips/alchemy/devboards/pb1500.c4
-rw-r--r--arch/mips/alchemy/devboards/platform.c30
-rw-r--r--arch/mips/alchemy/devboards/prom.c69
-rw-r--r--arch/mips/bcm63xx/Kconfig4
-rw-r--r--arch/mips/bcm63xx/Makefile3
-rw-r--r--arch/mips/bcm63xx/boards/board_bcm963xx.c107
-rw-r--r--arch/mips/bcm63xx/clk.c26
-rw-r--r--arch/mips/bcm63xx/cpu.c63
-rw-r--r--arch/mips/bcm63xx/dev-dsp.c2
-rw-r--r--arch/mips/bcm63xx/dev-flash.c123
-rw-r--r--arch/mips/bcm63xx/dev-rng.c40
-rw-r--r--arch/mips/bcm63xx/dev-spi.c119
-rw-r--r--arch/mips/bcm63xx/dev-wdt.c2
-rw-r--r--arch/mips/bcm63xx/irq.c21
-rw-r--r--arch/mips/bcm63xx/prom.c4
-rw-r--r--arch/mips/bcm63xx/setup.c13
-rw-r--r--arch/mips/boot/compressed/Makefile4
-rw-r--r--arch/mips/boot/compressed/uart-16550.c5
-rw-r--r--arch/mips/cavium-octeon/.gitignore2
-rw-r--r--arch/mips/cavium-octeon/Makefile16
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-fpa.c183
-rw-r--r--arch/mips/cavium-octeon/executive/cvmx-helper-fpa.c243
-rw-r--r--arch/mips/cavium-octeon/octeon-irq.c399
-rw-r--r--arch/mips/cavium-octeon/octeon-memcpy.S16
-rw-r--r--arch/mips/cavium-octeon/octeon-platform.c699
-rw-r--r--arch/mips/cavium-octeon/octeon_3xxx.dts571
-rw-r--r--arch/mips/cavium-octeon/octeon_68xx.dts625
-rw-r--r--arch/mips/cavium-octeon/serial.c134
-rw-r--r--arch/mips/cavium-octeon/setup.c45
-rw-r--r--arch/mips/configs/ls1b_defconfig109
-rw-r--r--arch/mips/configs/nlm_xlr_defconfig4
-rw-r--r--arch/mips/dec/prom/memory.c2
-rw-r--r--arch/mips/include/asm/clock.h11
-rw-r--r--arch/mips/include/asm/cpu.h3
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h150
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h12
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h89
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h2
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h8
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h286
-rw-r--r--arch/mips/include/asm/mach-bcm63xx/ioremap.h1
-rw-r--r--arch/mips/include/asm/mach-cavium-octeon/irq.h45
-rw-r--r--arch/mips/include/asm/mach-jz4740/jz4740_nand.h4
-rw-r--r--arch/mips/include/asm/mach-loongson/loongson.h4
-rw-r--r--arch/mips/include/asm/mach-loongson1/irq.h73
-rw-r--r--arch/mips/include/asm/mach-loongson1/loongson1.h44
-rw-r--r--arch/mips/include/asm/mach-loongson1/platform.h23
-rw-r--r--arch/mips/include/asm/mach-loongson1/prom.h24
-rw-r--r--arch/mips/include/asm/mach-loongson1/regs-clk.h33
-rw-r--r--arch/mips/include/asm/mach-loongson1/regs-wdt.h22
-rw-r--r--arch/mips/include/asm/mach-loongson1/war.h25
-rw-r--r--arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h1
-rw-r--r--arch/mips/include/asm/mach-tx49xx/mangle-port.h2
-rw-r--r--arch/mips/include/asm/mipsmtregs.h13
-rw-r--r--arch/mips/include/asm/module.h2
-rw-r--r--arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h4
-rw-r--r--arch/mips/include/asm/netlogic/xlp-hal/iomap.h5
-rw-r--r--arch/mips/include/asm/netlogic/xlp-hal/pcibus.h76
-rw-r--r--arch/mips/include/asm/netlogic/xlp-hal/pic.h4
-rw-r--r--arch/mips/include/asm/netlogic/xlp-hal/usb.h64
-rw-r--r--arch/mips/include/asm/netlogic/xlp-hal/xlp.h17
-rw-r--r--arch/mips/include/asm/netlogic/xlr/bridge.h104
-rw-r--r--arch/mips/include/asm/netlogic/xlr/flash.h55
-rw-r--r--arch/mips/include/asm/netlogic/xlr/gpio.h59
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper-fpa.h64
-rw-r--r--arch/mips/include/asm/octeon/cvmx-helper.h2
-rw-r--r--arch/mips/include/asm/octeon/octeon.h5
-rw-r--r--arch/mips/include/asm/prom.h3
-rw-r--r--arch/mips/include/asm/smtc.h6
-rw-r--r--arch/mips/include/asm/uaccess.h6
-rw-r--r--arch/mips/include/asm/uasm.h100
-rw-r--r--arch/mips/include/asm/unistd.h1
-rw-r--r--arch/mips/jz4740/board-qi_lb60.c1
-rw-r--r--arch/mips/jz4740/platform.c20
-rw-r--r--arch/mips/jz4740/reset.c49
-rw-r--r--arch/mips/kernel/cpu-probe.c299
-rw-r--r--arch/mips/kernel/cpufreq/Makefile2
-rw-r--r--arch/mips/kernel/cpufreq/loongson2_cpufreq.c21
-rw-r--r--arch/mips/kernel/perf_event_mipsxx.c5
-rw-r--r--arch/mips/kernel/prom.c29
-rw-r--r--arch/mips/kernel/smp.c4
-rw-r--r--arch/mips/kernel/smtc.c76
-rw-r--r--arch/mips/kernel/traps.c1
-rw-r--r--arch/mips/lantiq/clk.c5
-rw-r--r--arch/mips/lantiq/prom.c22
-rw-r--r--arch/mips/lantiq/xway/sysctrl.c49
-rw-r--r--arch/mips/lib/Makefile2
-rw-r--r--arch/mips/lib/memcpy-inatomic.S451
-rw-r--r--arch/mips/lib/memcpy.S11
-rw-r--r--arch/mips/loongson/Kconfig1
-rw-r--r--arch/mips/loongson/lemote-2f/Makefile2
-rw-r--r--arch/mips/loongson/lemote-2f/clock.c (renamed from arch/mips/kernel/cpufreq/loongson2_clock.c)46
-rw-r--r--arch/mips/loongson1/Kconfig22
-rw-r--r--arch/mips/loongson1/Makefile11
-rw-r--r--arch/mips/loongson1/Platform7
-rw-r--r--arch/mips/loongson1/common/Makefile5
-rw-r--r--arch/mips/loongson1/common/clock.c181
-rw-r--r--arch/mips/loongson1/common/irq.c147
-rw-r--r--arch/mips/loongson1/common/platform.c124
-rw-r--r--arch/mips/loongson1/common/prom.c87
-rw-r--r--arch/mips/loongson1/common/reset.c45
-rw-r--r--arch/mips/loongson1/common/setup.c29
-rw-r--r--arch/mips/loongson1/ls1b/Makefile5
-rw-r--r--arch/mips/loongson1/ls1b/board.c33
-rw-r--r--arch/mips/mm/uasm.c62
-rw-r--r--arch/mips/netlogic/common/earlycons.c2
-rw-r--r--arch/mips/netlogic/common/smpboot.S157
-rw-r--r--arch/mips/netlogic/xlp/Makefile2
-rw-r--r--arch/mips/netlogic/xlp/nlm_hal.c52
-rw-r--r--arch/mips/netlogic/xlp/of.c34
-rw-r--r--arch/mips/netlogic/xlp/platform.c2
-rw-r--r--arch/mips/netlogic/xlp/setup.c16
-rw-r--r--arch/mips/netlogic/xlp/usb-init.c124
-rw-r--r--arch/mips/netlogic/xlr/Makefile2
-rw-r--r--arch/mips/netlogic/xlr/platform-flash.c220
-rw-r--r--arch/mips/netlogic/xlr/platform.c140
-rw-r--r--arch/mips/netlogic/xlr/setup.c2
-rw-r--r--arch/mips/oprofile/common.c1
-rw-r--r--arch/mips/oprofile/op_model_mipsxx.c10
-rw-r--r--arch/mips/pci/Makefile1
-rw-r--r--arch/mips/pci/fixup-cobalt.c8
-rw-r--r--arch/mips/pci/fixup-malta.c14
-rw-r--r--arch/mips/pci/fixup-rc32434.c2
-rw-r--r--arch/mips/pci/ops-bcm63xx.c63
-rw-r--r--arch/mips/pci/pci-bcm63xx.c133
-rw-r--r--arch/mips/pci/pci-bcm63xx.h5
-rw-r--r--arch/mips/pci/pci-xlp.c248
-rw-r--r--arch/mips/pci/pci-xlr.c4
-rw-r--r--arch/mips/pnx833x/stb22x/board.c4
-rw-r--r--arch/mips/sgi-ip27/ip27-memory.c1
-rw-r--r--arch/mips/txx9/Kconfig1
-rw-r--r--arch/mips/txx9/generic/pci.c6
-rw-r--r--arch/mips/txx9/generic/setup.c12
-rw-r--r--arch/mips/txx9/generic/setup_tx4939.c2
-rw-r--r--arch/mips/txx9/rbtx4939/setup.c11
-rw-r--r--arch/mn10300/Kconfig1
-rw-r--r--arch/mn10300/include/asm/ipc.h1
-rw-r--r--arch/mn10300/include/asm/unistd.h1
-rw-r--r--arch/openrisc/include/asm/Kbuild2
-rw-r--r--arch/powerpc/Kconfig2
-rw-r--r--arch/powerpc/boot/dts/p2020rdb-pc_32b.dts4
-rw-r--r--arch/powerpc/boot/dts/p2020rdb-pc_36b.dts4
-rw-r--r--arch/powerpc/boot/dts/p3041ds.dts2
-rw-r--r--arch/powerpc/configs/chroma_defconfig4
-rw-r--r--arch/powerpc/include/asm/dma-mapping.h8
-rw-r--r--arch/powerpc/include/asm/unistd.h1
-rw-r--r--arch/powerpc/kernel/dma-iommu.c1
-rw-r--r--arch/powerpc/kernel/dma-swiotlb.c1
-rw-r--r--arch/powerpc/kernel/dma.c36
-rw-r--r--arch/powerpc/kernel/vio.c1
-rw-r--r--arch/powerpc/kvm/book3s_rmhandlers.S1
-rw-r--r--arch/powerpc/platforms/85xx/p1022_ds.c122
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c77
-rw-r--r--arch/powerpc/platforms/cell/spufs/syscalls.c2
-rw-r--r--arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h4
-rw-r--r--arch/powerpc/sysdev/fsl_85xx_l2ctlr.c39
-rw-r--r--arch/powerpc/sysdev/xics/icp-hv.c2
-rw-r--r--arch/powerpc/sysdev/xics/icp-native.c2
-rw-r--r--arch/powerpc/sysdev/xics/xics-common.c3
-rw-r--r--arch/s390/Kconfig3
-rw-r--r--arch/s390/defconfig7
-rw-r--r--arch/s390/include/asm/mmu_context.h16
-rw-r--r--arch/s390/include/asm/processor.h2
-rw-r--r--arch/s390/include/asm/setup.h2
-rw-r--r--arch/s390/include/asm/unistd.h1
-rw-r--r--arch/s390/kernel/debug.c70
-rw-r--r--arch/s390/kernel/dis.c4
-rw-r--r--arch/s390/kernel/early.c1
-rw-r--r--arch/s390/kernel/ipl.c12
-rw-r--r--arch/s390/kernel/setup.c12
-rw-r--r--arch/s390/kernel/traps.c16
-rw-r--r--arch/s390/kernel/vdso.c9
-rw-r--r--arch/s390/kernel/vmlinux.lds.S2
-rw-r--r--arch/s390/mm/fault.c35
-rw-r--r--arch/s390/mm/mmap.c12
-rw-r--r--arch/s390/mm/pgtable.c7
-rw-r--r--arch/s390/oprofile/backtrace.c2
-rw-r--r--arch/sh/Kconfig2
-rw-r--r--arch/sh/configs/apsh4ad0a_defconfig2
-rw-r--r--arch/sh/configs/sdk7786_defconfig4
-rw-r--r--arch/sh/configs/se7206_defconfig2
-rw-r--r--arch/sh/configs/shx3_defconfig2
-rw-r--r--arch/sh/configs/urquell_defconfig4
-rw-r--r--arch/sh/include/asm/unistd.h1
-rw-r--r--arch/sparc/Kconfig1
-rw-r--r--arch/sparc/include/asm/unistd.h1
-rw-r--r--arch/sparc/kernel/ldc.c6
-rw-r--r--arch/sparc/kernel/sys_sparc_64.c2
-rw-r--r--arch/tile/configs/tilegx_defconfig4
-rw-r--r--arch/tile/configs/tilepro_defconfig4
-rw-r--r--arch/tile/include/asm/Kbuild1
-rw-r--r--arch/um/defconfig10
-rw-r--r--arch/um/drivers/chan_kern.c4
-rw-r--r--arch/um/drivers/line.c231
-rw-r--r--arch/um/drivers/line.h12
-rw-r--r--arch/um/drivers/mconsole_kern.c3
-rw-r--r--arch/um/drivers/port_kern.c6
-rw-r--r--arch/um/drivers/random.c3
-rw-r--r--arch/um/drivers/ssl.c42
-rw-r--r--arch/um/drivers/stdio_console.c21
-rw-r--r--arch/um/drivers/ubd_kern.c2
-rw-r--r--arch/um/drivers/xterm_kern.c3
-rw-r--r--arch/um/include/asm/ptrace-generic.h2
-rw-r--r--arch/um/include/shared/as-layout.h3
-rw-r--r--arch/um/include/shared/irq_user.h3
-rw-r--r--arch/um/include/shared/kern_util.h13
-rw-r--r--arch/um/kernel/irq.c2
-rw-r--r--arch/um/kernel/process.c13
-rw-r--r--arch/um/kernel/ptrace.c71
-rw-r--r--arch/um/kernel/sigio.c3
-rw-r--r--arch/um/kernel/skas/syscall.c6
-rw-r--r--arch/um/kernel/time.c2
-rw-r--r--arch/um/kernel/trap.c39
-rw-r--r--arch/um/os-Linux/internal.h2
-rw-r--r--arch/um/os-Linux/signal.c26
-rw-r--r--arch/um/os-Linux/skas/process.c16
-rw-r--r--arch/um/os-Linux/time.c2
-rw-r--r--arch/x86/Kconfig2
-rw-r--r--arch/x86/include/asm/perf_event.h2
-rw-r--r--arch/x86/include/asm/unistd.h1
-rw-r--r--arch/x86/kernel/cpu/perf_event.h2
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel.c92
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore.c1316
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_uncore.h207
-rw-r--r--arch/x86/kernel/e820.c2
-rw-r--r--arch/x86/um/asm/ptrace.h6
-rw-r--r--arch/xtensa/Kconfig1
-rw-r--r--arch/xtensa/include/asm/cpumask.h16
-rw-r--r--arch/xtensa/include/asm/rmap.h16
-rw-r--r--arch/xtensa/kernel/syscall.c2
-rw-r--r--arch/xtensa/mm/fault.c29
396 files changed, 11544 insertions, 5804 deletions
diff --git a/arch/Kconfig b/arch/Kconfig
index 8c3d957fa8e..72f2fa189cc 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -248,7 +248,14 @@ config HAVE_CMPXCHG_LOCAL
config HAVE_CMPXCHG_DOUBLE
bool
+config ARCH_WANT_IPC_PARSE_VERSION
+ bool
+
+config ARCH_WANT_COMPAT_IPC_PARSE_VERSION
+ bool
+
config ARCH_WANT_OLD_COMPAT_IPC
+ select ARCH_WANT_COMPAT_IPC_PARSE_VERSION
bool
config HAVE_ARCH_SECCOMP_FILTER
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig
index 3de74c9f961..d5b9b5e645c 100644
--- a/arch/alpha/Kconfig
+++ b/arch/alpha/Kconfig
@@ -14,6 +14,7 @@ config ALPHA
select AUTO_IRQ_AFFINITY if SMP
select GENERIC_IRQ_SHOW
select ARCH_WANT_OPTIONAL_GPIOLIB
+ select ARCH_WANT_IPC_PARSE_VERSION
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_SMP_IDLE_THREAD
select GENERIC_CMOS_UPDATE
diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h
index d1f23b722df..633b23b0664 100644
--- a/arch/alpha/include/asm/unistd.h
+++ b/arch/alpha/include/asm/unistd.h
@@ -470,7 +470,6 @@
#define NR_SYSCALLS 504
-#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_GETHOSTNAME
diff --git a/arch/alpha/kernel/smc37c669.c b/arch/alpha/kernel/smc37c669.c
index 0435921d41c..c803fc76ae4 100644
--- a/arch/alpha/kernel/smc37c669.c
+++ b/arch/alpha/kernel/smc37c669.c
@@ -933,18 +933,6 @@ void SMC37c669_display_device_info(
*
*--
*/
-#if 0
-/* $INCLUDE_OPTIONS$ */
-#include "cp$inc:platform_io.h"
-/* $INCLUDE_OPTIONS_END$ */
-#include "cp$src:common.h"
-#include "cp$inc:prototypes.h"
-#include "cp$src:kernel_def.h"
-#include "cp$src:msg_def.h"
-#include "cp$src:smcc669_def.h"
-/* Platform-specific includes */
-#include "cp$src:platform.h"
-#endif
#ifndef TRUE
#define TRUE 1
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index fbdd8533c05..7980873525b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -11,6 +11,7 @@ config ARM
select RTC_LIB
select SYS_SUPPORTS_APM_EMULATION
select GENERIC_ATOMIC64 if (CPU_V6 || !CPU_32v6K || !AEABI)
+ select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
select HAVE_ARCH_KGDB
@@ -38,6 +39,7 @@ config ARM
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select GENERIC_IRQ_PROBE
+ select ARCH_WANT_IPC_PARSE_VERSION
select HARDIRQS_SW_RESEND
select CPU_PM if (SUSPEND || CPU_IDLE)
select GENERIC_PCI_IOMAP
@@ -1009,7 +1011,6 @@ config ARCH_VT8500
select ARCH_HAS_CPUFREQ
select GENERIC_CLOCKEVENTS
select ARCH_REQUIRE_GPIOLIB
- select HAVE_PWM
help
Support for VIA/WonderMedia VT8500/WM85xx System-on-Chip.
diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts
index 2e1cfa00c25..9fecf1ae777 100644
--- a/arch/arm/boot/dts/highbank.dts
+++ b/arch/arm/boot/dts/highbank.dts
@@ -130,6 +130,12 @@
clocks = <&eclk>;
};
+ memory-controller@fff00000 {
+ compatible = "calxeda,hb-ddr-ctrl";
+ reg = <0xfff00000 0x1000>;
+ interrupts = <0 91 4>;
+ };
+
ipc@fff20000 {
compatible = "arm,pl320", "arm,primecell";
reg = <0xfff20000 0x1000>;
@@ -275,6 +281,12 @@
};
};
+ sregs@fff3c200 {
+ compatible = "calxeda,hb-sregs-l2-ecc";
+ reg = <0xfff3c200 0x100>;
+ interrupts = <0 71 4 0 72 4>;
+ };
+
dma@fff3d000 {
compatible = "arm,pl330", "arm,primecell";
reg = <0xfff3d000 0x1000>;
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi
index 915db89e364..787efac68da 100644
--- a/arch/arm/boot/dts/imx28.dtsi
+++ b/arch/arm/boot/dts/imx28.dtsi
@@ -660,6 +660,7 @@
compatible = "fsl,imx28-i2c";
reg = <0x80058000 2000>;
interrupts = <111 68>;
+ clock-frequency = <100000>;
status = "disabled";
};
@@ -669,6 +670,7 @@
compatible = "fsl,imx28-i2c";
reg = <0x8005a000 2000>;
interrupts = <110 69>;
+ clock-frequency = <100000>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/r8a7740.dtsi b/arch/arm/boot/dts/r8a7740.dtsi
new file mode 100644
index 00000000000..798fa35c000
--- /dev/null
+++ b/arch/arm/boot/dts/r8a7740.dtsi
@@ -0,0 +1,21 @@
+/*
+ * Device Tree Source for the r8a7740 SoC
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "renesas,r8a7740";
+
+ cpus {
+ cpu@0 {
+ compatible = "arm,cortex-a9";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/sh7377.dtsi b/arch/arm/boot/dts/sh7377.dtsi
new file mode 100644
index 00000000000..767ee0796da
--- /dev/null
+++ b/arch/arm/boot/dts/sh7377.dtsi
@@ -0,0 +1,21 @@
+/*
+ * Device Tree Source for the sh7377 SoC
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ *
+ * This file is licensed under the terms of the GNU General Public License
+ * version 2. This program is licensed "as is" without any warranty of any
+ * kind, whether express or implied.
+ */
+
+/include/ "skeleton.dtsi"
+
+/ {
+ compatible = "renesas,sh7377";
+
+ cpus {
+ cpu@0 {
+ compatible = "arm,cortex-a8";
+ };
+ };
+};
diff --git a/arch/arm/boot/dts/tegra20.dtsi b/arch/arm/boot/dts/tegra20.dtsi
index 9f1921634eb..405d1673904 100644
--- a/arch/arm/boot/dts/tegra20.dtsi
+++ b/arch/arm/boot/dts/tegra20.dtsi
@@ -123,6 +123,12 @@
status = "disabled";
};
+ pwm {
+ compatible = "nvidia,tegra20-pwm";
+ reg = <0x7000a000 0x100>;
+ #pwm-cells = <2>;
+ };
+
i2c@7000c000 {
compatible = "nvidia,tegra20-i2c";
reg = <0x7000c000 0x100>;
diff --git a/arch/arm/boot/dts/tegra30.dtsi b/arch/arm/boot/dts/tegra30.dtsi
index da740191771..3e4334d14ef 100644
--- a/arch/arm/boot/dts/tegra30.dtsi
+++ b/arch/arm/boot/dts/tegra30.dtsi
@@ -117,6 +117,12 @@
status = "disabled";
};
+ pwm {
+ compatible = "nvidia,tegra30-pwm", "nvidia,tegra20-pwm";
+ reg = <0x7000a000 0x100>;
+ #pwm-cells = <2>;
+ };
+
i2c@7000c000 {
compatible = "nvidia,tegra30-i2c", "nvidia,tegra20-i2c";
reg = <0x7000c000 0x100>;
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index aa07f5938f0..1143c4d5c56 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -452,6 +452,7 @@ static struct dma_map_ops dmabounce_ops = {
.alloc = arm_dma_alloc,
.free = arm_dma_free,
.mmap = arm_dma_mmap,
+ .get_sgtable = arm_dma_get_sgtable,
.map_page = dmabounce_map_page,
.unmap_page = dmabounce_unmap_page,
.sync_single_for_cpu = dmabounce_sync_for_cpu,
diff --git a/arch/arm/configs/armadillo800eva_defconfig b/arch/arm/configs/armadillo800eva_defconfig
index ddc9fe6a78a..7d8718468e0 100644
--- a/arch/arm/configs/armadillo800eva_defconfig
+++ b/arch/arm/configs/armadillo800eva_defconfig
@@ -5,10 +5,7 @@ CONFIG_IKCONFIG_PROC=y
CONFIG_LOG_BUF_SHIFT=16
# CONFIG_UTS_NS is not set
# CONFIG_IPC_NS is not set
-# CONFIG_USER_NS is not set
# CONFIG_PID_NS is not set
-CONFIG_SYSFS_DEPRECATED=y
-CONFIG_SYSFS_DEPRECATED_V2=y
CONFIG_CC_OPTIMIZE_FOR_SIZE=y
CONFIG_SLAB=y
CONFIG_MODULES=y
@@ -21,7 +18,7 @@ CONFIG_ARCH_SHMOBILE=y
CONFIG_ARCH_R8A7740=y
CONFIG_MACH_ARMADILLO800EVA=y
# CONFIG_SH_TIMER_TMU is not set
-# CONFIG_ARM_THUMB is not set
+CONFIG_ARM_THUMB=y
CONFIG_CPU_BPREDICT_DISABLE=y
# CONFIG_CACHE_L2X0 is not set
CONFIG_ARM_ERRATA_430973=y
@@ -39,6 +36,7 @@ CONFIG_ZBOOT_ROM_BSS=0x0
CONFIG_CMDLINE="console=tty0 console=ttySC1,115200 earlyprintk=sh-sci.1,115200 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096"
CONFIG_CMDLINE_FORCE=y
CONFIG_KEXEC=y
+CONFIG_VFP=y
# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
# CONFIG_SUSPEND is not set
CONFIG_NET=y
@@ -89,26 +87,32 @@ CONFIG_SERIAL_SH_SCI_CONSOLE=y
CONFIG_I2C=y
CONFIG_I2C_SH_MOBILE=y
# CONFIG_HWMON is not set
+CONFIG_MEDIA_SUPPORT=y
+CONFIG_VIDEO_DEV=y
+# CONFIG_RC_CORE is not set
+# CONFIG_VIDEO_HELPER_CHIPS_AUTO is not set
+# CONFIG_V4L_USB_DRIVERS is not set
+CONFIG_V4L_PLATFORM_DRIVERS=y
+CONFIG_SOC_CAMERA=y
+CONFIG_SOC_CAMERA_MT9T112=y
+CONFIG_VIDEO_SH_MOBILE_CEU=y
+# CONFIG_RADIO_ADAPTERS is not set
CONFIG_FB=y
-CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_SH_MOBILE_LCDC=y
+CONFIG_FB_SH_MOBILE_HDMI=y
CONFIG_LCD_CLASS_DEVICE=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY=y
CONFIG_LOGO=y
# CONFIG_LOGO_LINUX_MONO is not set
# CONFIG_LOGO_LINUX_VGA16 is not set
-CONFIG_SOUND=y
-CONFIG_SND=y
# CONFIG_SND_SUPPORT_OLD_API is not set
# CONFIG_SND_VERBOSE_PROCFS is not set
# CONFIG_SND_DRIVERS is not set
# CONFIG_SND_ARM is not set
-CONFIG_SND_SOC=y
CONFIG_SND_SOC_SH4_FSI=y
# CONFIG_HID_SUPPORT is not set
CONFIG_USB=y
-# CONFIG_USB_DEVICE_CLASS is not set
CONFIG_USB_RENESAS_USBHS=y
CONFIG_USB_GADGET=y
CONFIG_USB_RENESAS_USBHS_UDC=y
@@ -116,6 +120,8 @@ CONFIG_USB_ETH=m
CONFIG_MMC=y
CONFIG_MMC_SDHI=y
CONFIG_MMC_SH_MMCIF=y
+CONFIG_DMADEVICES=y
+CONFIG_SH_DMAE=y
CONFIG_UIO=y
CONFIG_UIO_PDRV_GENIRQ=y
# CONFIG_DNOTIFY is not set
@@ -124,7 +130,6 @@ CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
# CONFIG_MISC_FILESYSTEMS is not set
CONFIG_NFS_FS=y
-CONFIG_NFS_V3=y
CONFIG_NFS_V3_ACL=y
CONFIG_NFS_V4=y
CONFIG_NFS_V4_1=y
diff --git a/arch/arm/configs/kzm9d_defconfig b/arch/arm/configs/kzm9d_defconfig
new file mode 100644
index 00000000000..26146ffea1a
--- /dev/null
+++ b/arch/arm/configs/kzm9d_defconfig
@@ -0,0 +1,89 @@
+# CONFIG_ARM_PATCH_PHYS_VIRT is not set
+CONFIG_EXPERIMENTAL=y
+CONFIG_SYSVIPC=y
+CONFIG_NO_HZ=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_EMBEDDED=y
+CONFIG_SLAB=y
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_IOSCHED_DEADLINE is not set
+# CONFIG_IOSCHED_CFQ is not set
+CONFIG_ARCH_SHMOBILE=y
+CONFIG_ARCH_EMEV2=y
+CONFIG_MACH_KZM9D=y
+CONFIG_MEMORY_START=0x40000000
+CONFIG_MEMORY_SIZE=0x10000000
+# CONFIG_SH_TIMER_TMU is not set
+# CONFIG_SWP_EMULATE is not set
+# CONFIG_CACHE_L2X0 is not set
+CONFIG_SMP=y
+CONFIG_NR_CPUS=2
+CONFIG_HOTPLUG_CPU=y
+# CONFIG_LOCAL_TIMERS is not set
+CONFIG_AEABI=y
+# CONFIG_OABI_COMPAT is not set
+# CONFIG_CROSS_MEMORY_ATTACH is not set
+CONFIG_FORCE_MAX_ZONEORDER=13
+CONFIG_ZBOOT_ROM_TEXT=0x0
+CONFIG_ZBOOT_ROM_BSS=0x0
+CONFIG_ARM_APPENDED_DTB=y
+CONFIG_CMDLINE="console=tty0 console=ttyS1,115200n81 earlyprintk=serial8250-em.1,115200n81 mem=128M@0x40000000 ignore_loglevel root=/dev/nfs ip=dhcp nfsroot=,rsize=4096,wsize=4096"
+CONFIG_CMDLINE_FORCE=y
+CONFIG_VFP=y
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_LRO is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+# CONFIG_BLK_DEV is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_CIRRUS is not set
+# CONFIG_NET_VENDOR_FARADAY is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+CONFIG_SMSC911X=y
+# CONFIG_NET_VENDOR_STMICRO is not set
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_WLAN is not set
+# CONFIG_INPUT_MOUSEDEV is not set
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+# CONFIG_LEGACY_PTYS is not set
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+CONFIG_SERIAL_8250_EM=y
+# CONFIG_HW_RANDOM is not set
+CONFIG_GPIOLIB=y
+CONFIG_GPIO_EM=y
+# CONFIG_HWMON is not set
+# CONFIG_HID_SUPPORT is not set
+# CONFIG_USB_SUPPORT is not set
+# CONFIG_IOMMU_SUPPORT is not set
+# CONFIG_DNOTIFY is not set
+CONFIG_TMPFS=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+# CONFIG_FTRACE is not set
diff --git a/arch/arm/configs/kzm9g_defconfig b/arch/arm/configs/kzm9g_defconfig
index e3ebc20ed0a..2388c861062 100644
--- a/arch/arm/configs/kzm9g_defconfig
+++ b/arch/arm/configs/kzm9g_defconfig
@@ -100,7 +100,12 @@ CONFIG_SND_SOC_SH4_FSI=y
CONFIG_USB=y
CONFIG_USB_DEVICEFS=y
CONFIG_USB_R8A66597_HCD=y
+CONFIG_USB_RENESAS_USBHS=y
CONFIG_USB_STORAGE=y
+CONFIG_USB_GADGET=y
+CONFIG_USB_RENESAS_USBHS_UDC=y
+CONFIG_USB_ETH=m
+CONFIG_USB_MASS_STORAGE=m
CONFIG_MMC=y
# CONFIG_MMC_BLOCK_BOUNCE is not set
CONFIG_MMC_SDHI=y
@@ -108,12 +113,13 @@ CONFIG_MMC_SH_MMCIF=y
CONFIG_NEW_LEDS=y
CONFIG_LEDS_CLASS=y
CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_RS5C372=y
CONFIG_DMADEVICES=y
CONFIG_SH_DMAE=y
CONFIG_ASYNC_TX_DMA=y
CONFIG_STAGING=y
# CONFIG_DNOTIFY is not set
-# CONFIG_INOTIFY_USER is not set
+CONFIG_INOTIFY_USER=y
CONFIG_VFAT_FS=y
CONFIG_TMPFS=y
# CONFIG_MISC_FILESYSTEMS is not set
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index b152de79fd9..e58edc36b40 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -193,6 +193,8 @@ CONFIG_MMC_OMAP_HS=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_TWL92330=y
CONFIG_RTC_DRV_TWL4030=y
+CONFIG_DMADEVICES=y
+CONFIG_DMA_OMAP=y
CONFIG_EXT2_FS=y
CONFIG_EXT3_FS=y
# CONFIG_EXT3_FS_XATTR is not set
diff --git a/arch/arm/configs/tegra_defconfig b/arch/arm/configs/tegra_defconfig
index 4be9c1e80ee..db2245353f0 100644
--- a/arch/arm/configs/tegra_defconfig
+++ b/arch/arm/configs/tegra_defconfig
@@ -106,6 +106,7 @@ CONFIG_I2C_TEGRA=y
CONFIG_SPI=y
CONFIG_SPI_TEGRA=y
CONFIG_GPIO_TPS65910=y
+CONFIG_GPIO_TPS6586X=y
CONFIG_POWER_SUPPLY=y
CONFIG_BATTERY_SBS=y
CONFIG_SENSORS_LM90=y
diff --git a/arch/arm/include/asm/cacheflush.h b/arch/arm/include/asm/cacheflush.h
index 004c1bc95d2..e4448e16046 100644
--- a/arch/arm/include/asm/cacheflush.h
+++ b/arch/arm/include/asm/cacheflush.h
@@ -215,7 +215,9 @@ static inline void vivt_flush_cache_mm(struct mm_struct *mm)
static inline void
vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned long end)
{
- if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm)))
+ struct mm_struct *mm = vma->vm_mm;
+
+ if (!mm || cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm)))
__cpuc_flush_user_range(start & PAGE_MASK, PAGE_ALIGN(end),
vma->vm_flags);
}
@@ -223,7 +225,9 @@ vivt_flush_cache_range(struct vm_area_struct *vma, unsigned long start, unsigned
static inline void
vivt_flush_cache_page(struct vm_area_struct *vma, unsigned long user_addr, unsigned long pfn)
{
- if (cpumask_test_cpu(smp_processor_id(), mm_cpumask(vma->vm_mm))) {
+ struct mm_struct *mm = vma->vm_mm;
+
+ if (!mm || cpumask_test_cpu(smp_processor_id(), mm_cpumask(mm))) {
unsigned long addr = user_addr & PAGE_MASK;
__cpuc_flush_user_range(addr, addr + PAGE_SIZE, vma->vm_flags);
}
diff --git a/arch/arm/include/asm/dma-mapping.h b/arch/arm/include/asm/dma-mapping.h
index bbef15d0489..2ae842df455 100644
--- a/arch/arm/include/asm/dma-mapping.h
+++ b/arch/arm/include/asm/dma-mapping.h
@@ -186,17 +186,6 @@ extern int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
void *cpu_addr, dma_addr_t dma_addr, size_t size,
struct dma_attrs *attrs);
-#define dma_mmap_coherent(d, v, c, h, s) dma_mmap_attrs(d, v, c, h, s, NULL)
-
-static inline int dma_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t dma_addr,
- size_t size, struct dma_attrs *attrs)
-{
- struct dma_map_ops *ops = get_dma_ops(dev);
- BUG_ON(!ops);
- return ops->mmap(dev, vma, cpu_addr, dma_addr, size, attrs);
-}
-
static inline void *dma_alloc_writecombine(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag)
{
@@ -213,20 +202,12 @@ static inline void dma_free_writecombine(struct device *dev, size_t size,
return dma_free_attrs(dev, size, cpu_addr, dma_handle, &attrs);
}
-static inline int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t dma_addr, size_t size)
-{
- DEFINE_DMA_ATTRS(attrs);
- dma_set_attr(DMA_ATTR_WRITE_COMBINE, &attrs);
- return dma_mmap_attrs(dev, vma, cpu_addr, dma_addr, size, &attrs);
-}
-
/*
* This can be called during boot to increase the size of the consistent
* DMA region above it's default value of 2MB. It must be called before the
* memory allocator is initialised, i.e. before any core_initcall.
*/
-extern void __init init_consistent_dma_size(unsigned long size);
+static inline void init_consistent_dma_size(unsigned long size) { }
/*
* For SA-1111, IXP425, and ADI systems the dma-mapping functions are "magic"
@@ -280,6 +261,9 @@ extern void arm_dma_sync_sg_for_cpu(struct device *, struct scatterlist *, int,
enum dma_data_direction);
extern void arm_dma_sync_sg_for_device(struct device *, struct scatterlist *, int,
enum dma_data_direction);
+extern int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
+ void *cpu_addr, dma_addr_t dma_addr, size_t size,
+ struct dma_attrs *attrs);
#endif /* __KERNEL__ */
#endif
diff --git a/arch/arm/include/asm/mutex.h b/arch/arm/include/asm/mutex.h
index 93226cf23ae..b1479fd04a9 100644
--- a/arch/arm/include/asm/mutex.h
+++ b/arch/arm/include/asm/mutex.h
@@ -7,121 +7,10 @@
*/
#ifndef _ASM_MUTEX_H
#define _ASM_MUTEX_H
-
-#if __LINUX_ARM_ARCH__ < 6
-/* On pre-ARMv6 hardware the swp based implementation is the most efficient. */
-# include <asm-generic/mutex-xchg.h>
-#else
-
/*
- * Attempting to lock a mutex on ARMv6+ can be done with a bastardized
- * atomic decrement (it is not a reliable atomic decrement but it satisfies
- * the defined semantics for our purpose, while being smaller and faster
- * than a real atomic decrement or atomic swap. The idea is to attempt
- * decrementing the lock value only once. If once decremented it isn't zero,
- * or if its store-back fails due to a dispute on the exclusive store, we
- * simply bail out immediately through the slow path where the lock will be
- * reattempted until it succeeds.
+ * On pre-ARMv6 hardware this results in a swp-based implementation,
+ * which is the most efficient. For ARMv6+, we emit a pair of exclusive
+ * accesses instead.
*/
-static inline void
-__mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
-{
- int __ex_flag, __res;
-
- __asm__ (
-
- "ldrex %0, [%2] \n\t"
- "sub %0, %0, #1 \n\t"
- "strex %1, %0, [%2] "
-
- : "=&r" (__res), "=&r" (__ex_flag)
- : "r" (&(count)->counter)
- : "cc","memory" );
-
- __res |= __ex_flag;
- if (unlikely(__res != 0))
- fail_fn(count);
-}
-
-static inline int
-__mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *))
-{
- int __ex_flag, __res;
-
- __asm__ (
-
- "ldrex %0, [%2] \n\t"
- "sub %0, %0, #1 \n\t"
- "strex %1, %0, [%2] "
-
- : "=&r" (__res), "=&r" (__ex_flag)
- : "r" (&(count)->counter)
- : "cc","memory" );
-
- __res |= __ex_flag;
- if (unlikely(__res != 0))
- __res = fail_fn(count);
- return __res;
-}
-
-/*
- * Same trick is used for the unlock fast path. However the original value,
- * rather than the result, is used to test for success in order to have
- * better generated assembly.
- */
-static inline void
-__mutex_fastpath_unlock(atomic_t *count, void (*fail_fn)(atomic_t *))
-{
- int __ex_flag, __res, __orig;
-
- __asm__ (
-
- "ldrex %0, [%3] \n\t"
- "add %1, %0, #1 \n\t"
- "strex %2, %1, [%3] "
-
- : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag)
- : "r" (&(count)->counter)
- : "cc","memory" );
-
- __orig |= __ex_flag;
- if (unlikely(__orig != 0))
- fail_fn(count);
-}
-
-/*
- * If the unlock was done on a contended lock, or if the unlock simply fails
- * then the mutex remains locked.
- */
-#define __mutex_slowpath_needs_to_unlock() 1
-
-/*
- * For __mutex_fastpath_trylock we use another construct which could be
- * described as a "single value cmpxchg".
- *
- * This provides the needed trylock semantics like cmpxchg would, but it is
- * lighter and less generic than a true cmpxchg implementation.
- */
-static inline int
-__mutex_fastpath_trylock(atomic_t *count, int (*fail_fn)(atomic_t *))
-{
- int __ex_flag, __res, __orig;
-
- __asm__ (
-
- "1: ldrex %0, [%3] \n\t"
- "subs %1, %0, #1 \n\t"
- "strexeq %2, %1, [%3] \n\t"
- "movlt %0, #0 \n\t"
- "cmpeq %2, #0 \n\t"
- "bgt 1b "
-
- : "=&r" (__orig), "=&r" (__res), "=&r" (__ex_flag)
- : "r" (&count->counter)
- : "cc", "memory" );
-
- return __orig;
-}
-
-#endif
+#include <asm-generic/mutex-xchg.h>
#endif
diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h
index 23ebc0c82a3..24d284a1bfc 100644
--- a/arch/arm/include/asm/setup.h
+++ b/arch/arm/include/asm/setup.h
@@ -196,7 +196,7 @@ static const struct tagtable __tagtable_##fn __tag = { tag, fn }
struct membank {
phys_addr_t start;
- unsigned long size;
+ phys_addr_t size;
unsigned int highmem;
};
@@ -217,7 +217,7 @@ extern struct meminfo meminfo;
#define bank_phys_end(bank) ((bank)->start + (bank)->size)
#define bank_phys_size(bank) (bank)->size
-extern int arm_add_memory(phys_addr_t start, unsigned long size);
+extern int arm_add_memory(phys_addr_t start, phys_addr_t size);
extern void early_print(const char *str, ...);
extern void dump_machine_table(void);
diff --git a/arch/arm/include/asm/unistd.h b/arch/arm/include/asm/unistd.h
index 512cd147345..0cab47d4a83 100644
--- a/arch/arm/include/asm/unistd.h
+++ b/arch/arm/include/asm/unistd.h
@@ -446,7 +446,6 @@
#ifdef __KERNEL__
-#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_GETHOSTNAME
#define __ARCH_WANT_SYS_PAUSE
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 0d1851ca6eb..0f82098c9bf 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -244,6 +244,19 @@ svc_preempt:
b 1b
#endif
+__und_fault:
+ @ Correct the PC such that it is pointing at the instruction
+ @ which caused the fault. If the faulting instruction was ARM
+ @ the PC will be pointing at the next instruction, and have to
+ @ subtract 4. Otherwise, it is Thumb, and the PC will be
+ @ pointing at the second half of the Thumb instruction. We
+ @ have to subtract 2.
+ ldr r2, [r0, #S_PC]
+ sub r2, r2, r1
+ str r2, [r0, #S_PC]
+ b do_undefinstr
+ENDPROC(__und_fault)
+
.align 5
__und_svc:
#ifdef CONFIG_KPROBES
@@ -261,25 +274,32 @@ __und_svc:
@
@ r0 - instruction
@
-#ifndef CONFIG_THUMB2_KERNEL
+#ifndef CONFIG_THUMB2_KERNEL
ldr r0, [r4, #-4]
#else
+ mov r1, #2
ldrh r0, [r4, #-2] @ Thumb instruction at LR - 2
cmp r0, #0xe800 @ 32-bit instruction if xx >= 0
- ldrhhs r9, [r4] @ bottom 16 bits
- orrhs r0, r9, r0, lsl #16
+ blo __und_svc_fault
+ ldrh r9, [r4] @ bottom 16 bits
+ add r4, r4, #2
+ str r4, [sp, #S_PC]
+ orr r0, r9, r0, lsl #16
#endif
- adr r9, BSYM(1f)
+ adr r9, BSYM(__und_svc_finish)
mov r2, r4
bl call_fpe
+ mov r1, #4 @ PC correction to apply
+__und_svc_fault:
mov r0, sp @ struct pt_regs *regs
- bl do_undefinstr
+ bl __und_fault
@
@ IRQs off again before pulling preserved data off the stack
@
-1: disable_irq_notrace
+__und_svc_finish:
+ disable_irq_notrace
@
@ restore SPSR and restart the instruction
@@ -423,25 +443,33 @@ __und_usr:
mov r2, r4
mov r3, r5
+ @ r2 = regs->ARM_pc, which is either 2 or 4 bytes ahead of the
+ @ faulting instruction depending on Thumb mode.
+ @ r3 = regs->ARM_cpsr
@
- @ fall through to the emulation code, which returns using r9 if
- @ it has emulated the instruction, or the more conventional lr
- @ if we are to treat this as a real undefined instruction
- @
- @ r0 - instruction
+ @ The emulation code returns using r9 if it has emulated the
+ @ instruction, or the more conventional lr if we are to treat
+ @ this as a real undefined instruction
@
adr r9, BSYM(ret_from_exception)
- adr lr, BSYM(__und_usr_unknown)
+
tst r3, #PSR_T_BIT @ Thumb mode?
- itet eq @ explicit IT needed for the 1f label
- subeq r4, r2, #4 @ ARM instr at LR - 4
- subne r4, r2, #2 @ Thumb instr at LR - 2
-1: ldreqt r0, [r4]
+ bne __und_usr_thumb
+ sub r4, r2, #4 @ ARM instr at LR - 4
+1: ldrt r0, [r4]
#ifdef CONFIG_CPU_ENDIAN_BE8
- reveq r0, r0 @ little endian instruction
+ rev r0, r0 @ little endian instruction
#endif
- beq call_fpe
+ @ r0 = 32-bit ARM instruction which caused the exception
+ @ r2 = PC value for the following instruction (:= regs->ARM_pc)
+ @ r4 = PC value for the faulting instruction
+ @ lr = 32-bit undefined instruction function
+ adr lr, BSYM(__und_usr_fault_32)
+ b call_fpe
+
+__und_usr_thumb:
@ Thumb instruction
+ sub r4, r2, #2 @ First half of thumb instr at LR - 2
#if CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7
/*
* Thumb-2 instruction handling. Note that because pre-v6 and >= v6 platforms
@@ -455,7 +483,7 @@ __und_usr:
ldr r5, .LCcpu_architecture
ldr r5, [r5]
cmp r5, #CPU_ARCH_ARMv7
- blo __und_usr_unknown
+ blo __und_usr_fault_16 @ 16bit undefined instruction
/*
* The following code won't get run unless the running CPU really is v7, so
* coding round the lack of ldrht on older arches is pointless. Temporarily
@@ -463,15 +491,18 @@ __und_usr:
*/
.arch armv6t2
#endif
-2:
- ARM( ldrht r5, [r4], #2 )
- THUMB( ldrht r5, [r4] )
- THUMB( add r4, r4, #2 )
+2: ldrht r5, [r4]
cmp r5, #0xe800 @ 32bit instruction if xx != 0
- blo __und_usr_unknown
-3: ldrht r0, [r4]
+ blo __und_usr_fault_16 @ 16bit undefined instruction
+3: ldrht r0, [r2]
add r2, r2, #2 @ r2 is PC + 2, make it PC + 4
+ str r2, [sp, #S_PC] @ it's a 2x16bit instr, update
orr r0, r0, r5, lsl #16
+ adr lr, BSYM(__und_usr_fault_32)
+ @ r0 = the two 16-bit Thumb instructions which caused the exception
+ @ r2 = PC value for the following Thumb instruction (:= regs->ARM_pc)
+ @ r4 = PC value for the first 16-bit Thumb instruction
+ @ lr = 32bit undefined instruction function
#if __LINUX_ARM_ARCH__ < 7
/* If the target arch was overridden, change it back: */
@@ -482,17 +513,13 @@ __und_usr:
#endif
#endif /* __LINUX_ARM_ARCH__ < 7 */
#else /* !(CONFIG_ARM_THUMB && __LINUX_ARM_ARCH__ >= 6 && CONFIG_CPU_V7) */
- b __und_usr_unknown
+ b __und_usr_fault_16
#endif
- UNWIND(.fnend )
+ UNWIND(.fnend)
ENDPROC(__und_usr)
- @
- @ fallthrough to call_fpe
- @
-
/*
- * The out of line fixup for the ldrt above.
+ * The out of line fixup for the ldrt instructions above.
*/
.pushsection .fixup, "ax"
.align 2
@@ -524,11 +551,12 @@ ENDPROC(__und_usr)
* NEON handler code.
*
* Emulators may wish to make use of the following registers:
- * r0 = instruction opcode.
- * r2 = PC+4
+ * r0 = instruction opcode (32-bit ARM or two 16-bit Thumb)
+ * r2 = PC value to resume execution after successful emulation
* r9 = normal "successful" return address
- * r10 = this threads thread_info structure.
+ * r10 = this threads thread_info structure
* lr = unrecognised instruction return address
+ * IRQs disabled, FIQs enabled.
*/
@
@ Fall-through from Thumb-2 __und_usr
@@ -659,12 +687,17 @@ ENTRY(no_fp)
mov pc, lr
ENDPROC(no_fp)
-__und_usr_unknown:
- enable_irq
+__und_usr_fault_32:
+ mov r1, #4
+ b 1f
+__und_usr_fault_16:
+ mov r1, #2
+1: enable_irq
mov r0, sp
adr lr, BSYM(ret_from_exception)
- b do_undefinstr
-ENDPROC(__und_usr_unknown)
+ b __und_fault
+ENDPROC(__und_usr_fault_32)
+ENDPROC(__und_usr_fault_16)
.align 5
__pabt_usr:
diff --git a/arch/arm/kernel/entry-common.S b/arch/arm/kernel/entry-common.S
index 49d9f930524..978eac57e04 100644
--- a/arch/arm/kernel/entry-common.S
+++ b/arch/arm/kernel/entry-common.S
@@ -51,23 +51,15 @@ ret_fast_syscall:
fast_work_pending:
str r0, [sp, #S_R0+S_OFF]! @ returned r0
work_pending:
- tst r1, #_TIF_NEED_RESCHED
- bne work_resched
- /*
- * TIF_SIGPENDING or TIF_NOTIFY_RESUME must've been set if we got here
- */
- ldr r2, [sp, #S_PSR]
mov r0, sp @ 'regs'
- tst r2, #15 @ are we returning to user mode?
- bne no_work_pending @ no? just leave, then...
mov r2, why @ 'syscall'
- tst r1, #_TIF_SIGPENDING @ delivering a signal?
- movne why, #0 @ prevent further restarts
- bl do_notify_resume
- b ret_slow_syscall @ Check work again
+ bl do_work_pending
+ cmp r0, #0
+ beq no_work_pending
+ movlt scno, #(__NR_restart_syscall - __NR_SYSCALL_BASE)
+ ldmia sp, {r0 - r6} @ have to reload r0 - r6
+ b local_restart @ ... and off we go
-work_resched:
- bl schedule
/*
* "slow" syscall return path. "why" tells us if this was a real syscall.
*/
@@ -409,6 +401,7 @@ ENTRY(vector_swi)
eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
#endif
+local_restart:
ldr r10, [tsk, #TI_FLAGS] @ check for syscall tracing
stmdb sp!, {r4, r5} @ push fifth and sixth args
@@ -450,7 +443,8 @@ __sys_trace:
mov scno, r0 @ syscall number (possibly new)
add r1, sp, #S_R0 + S_OFF @ pointer to regs
cmp scno, #NR_syscalls @ check upper syscall limit
- ldmccia r1, {r0 - r3} @ have to reload r0 - r3
+ ldmccia r1, {r0 - r6} @ have to reload r0 - r6
+ stmccia sp, {r4, r5} @ and update the stack args
ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
b 2b
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index df0bf0c8cb7..34e56647dce 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -179,19 +179,20 @@ void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr,
old = *parent;
*parent = return_hooker;
- err = ftrace_push_return_trace(old, self_addr, &trace.depth,
- frame_pointer);
- if (err == -EBUSY) {
- *parent = old;
- return;
- }
-
trace.func = self_addr;
+ trace.depth = current->curr_ret_stack + 1;
/* Only trace if the calling function expects to */
if (!ftrace_graph_entry(&trace)) {
- current->curr_ret_stack--;
*parent = old;
+ return;
+ }
+
+ err = ftrace_push_return_trace(old, self_addr, &trace.depth,
+ frame_pointer);
+ if (err == -EBUSY) {
+ *parent = old;
+ return;
}
}
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index 19c95ea65b2..693b744fd57 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -247,6 +247,7 @@ void machine_shutdown(void)
void machine_halt(void)
{
machine_shutdown();
+ local_irq_disable();
while (1);
}
@@ -268,6 +269,7 @@ void machine_restart(char *cmd)
/* Whoops - the platform was unable to reboot. Tell the user! */
printk("Reboot failed -- System halted\n");
+ local_irq_disable();
while (1);
}
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index dab711e6e1c..3e0fc5f7ed4 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -25,6 +25,7 @@
#include <linux/regset.h>
#include <linux/audit.h>
#include <linux/tracehook.h>
+#include <linux/unistd.h>
#include <asm/pgtable.h>
#include <asm/traps.h>
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index e15d83bb4ea..a81dcecc734 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -508,7 +508,7 @@ void __init dump_machine_table(void)
/* can't use cpu_relax() here as it may require MMU setup */;
}
-int __init arm_add_memory(phys_addr_t start, unsigned long size)
+int __init arm_add_memory(phys_addr_t start, phys_addr_t size)
{
struct membank *bank = &meminfo.bank[meminfo.nr_banks];
@@ -538,7 +538,7 @@ int __init arm_add_memory(phys_addr_t start, unsigned long size)
}
#endif
- bank->size = size & PAGE_MASK;
+ bank->size = size & ~(phys_addr_t)(PAGE_SIZE - 1);
/*
* Check whether this memory region has non-zero size or
@@ -558,7 +558,7 @@ int __init arm_add_memory(phys_addr_t start, unsigned long size)
static int __init early_mem(char *p)
{
static int usermem __initdata = 0;
- unsigned long size;
+ phys_addr_t size;
phys_addr_t start;
char *endp;
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 536c5d6b340..f27789e4e38 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -27,7 +27,6 @@
*/
#define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)|(__NR_OABI_SYSCALL_BASE))
#define SWI_SYS_RT_SIGRETURN (0xef000000|(__NR_rt_sigreturn)|(__NR_OABI_SYSCALL_BASE))
-#define SWI_SYS_RESTART (0xef000000|__NR_restart_syscall|__NR_OABI_SYSCALL_BASE)
/*
* With EABI, the syscall number has to be loaded into r7.
@@ -48,18 +47,6 @@ const unsigned long sigreturn_codes[7] = {
};
/*
- * Either we support OABI only, or we have EABI with the OABI
- * compat layer enabled. In the later case we don't know if
- * user space is EABI or not, and if not we must not clobber r7.
- * Always using the OABI syscall solves that issue and works for
- * all those cases.
- */
-const unsigned long syscall_restart_code[2] = {
- SWI_SYS_RESTART, /* swi __NR_restart_syscall */
- 0xe49df004, /* ldr pc, [sp], #4 */
-};
-
-/*
* atomically swap in the new signal mask, and wait for a signal.
*/
asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, old_sigset_t mask)
@@ -582,12 +569,13 @@ handle_signal(unsigned long sig, struct k_sigaction *ka,
* the kernel can handle, and then we build all the user-level signal handling
* stack-frames in one go after that.
*/
-static void do_signal(struct pt_regs *regs, int syscall)
+static int do_signal(struct pt_regs *regs, int syscall)
{
unsigned int retval = 0, continue_addr = 0, restart_addr = 0;
struct k_sigaction ka;
siginfo_t info;
int signr;
+ int restart = 0;
/*
* If we were from a system call, check for system call restarting...
@@ -602,15 +590,15 @@ static void do_signal(struct pt_regs *regs, int syscall)
* debugger will see the already changed PSW.
*/
switch (retval) {
+ case -ERESTART_RESTARTBLOCK:
+ restart -= 2;
case -ERESTARTNOHAND:
case -ERESTARTSYS:
case -ERESTARTNOINTR:
+ restart++;
regs->ARM_r0 = regs->ARM_ORIG_r0;
regs->ARM_pc = restart_addr;
break;
- case -ERESTART_RESTARTBLOCK:
- regs->ARM_r0 = -EINTR;
- break;
}
}
@@ -619,14 +607,17 @@ static void do_signal(struct pt_regs *regs, int syscall)
* point the debugger may change all our registers ...
*/
signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+ /*
+ * Depending on the signal settings we may need to revert the
+ * decision to restart the system call. But skip this if a
+ * debugger has chosen to restart at a different PC.
+ */
+ if (regs->ARM_pc != restart_addr)
+ restart = 0;
if (signr > 0) {
- /*
- * Depending on the signal settings we may need to revert the
- * decision to restart the system call. But skip this if a
- * debugger has chosen to restart at a different PC.
- */
- if (regs->ARM_pc == restart_addr) {
- if (retval == -ERESTARTNOHAND
+ if (unlikely(restart)) {
+ if (retval == -ERESTARTNOHAND ||
+ retval == -ERESTART_RESTARTBLOCK
|| (retval == -ERESTARTSYS
&& !(ka.sa.sa_flags & SA_RESTART))) {
regs->ARM_r0 = -EINTR;
@@ -635,52 +626,43 @@ static void do_signal(struct pt_regs *regs, int syscall)
}
handle_signal(signr, &ka, &info, regs);
- return;
- }
-
- if (syscall) {
- /*
- * Handle restarting a different system call. As above,
- * if a debugger has chosen to restart at a different PC,
- * ignore the restart.
- */
- if (retval == -ERESTART_RESTARTBLOCK
- && regs->ARM_pc == continue_addr) {
- if (thumb_mode(regs)) {
- regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE;
- regs->ARM_pc -= 2;
- } else {
-#if defined(CONFIG_AEABI) && !defined(CONFIG_OABI_COMPAT)
- regs->ARM_r7 = __NR_restart_syscall;
- regs->ARM_pc -= 4;
-#else
- u32 __user *usp;
-
- regs->ARM_sp -= 4;
- usp = (u32 __user *)regs->ARM_sp;
-
- if (put_user(regs->ARM_pc, usp) == 0) {
- regs->ARM_pc = KERN_RESTART_CODE;
- } else {
- regs->ARM_sp += 4;
- force_sigsegv(0, current);
- }
-#endif
- }
- }
+ return 0;
}
restore_saved_sigmask();
+ if (unlikely(restart))
+ regs->ARM_pc = continue_addr;
+ return restart;
}
-asmlinkage void
-do_notify_resume(struct pt_regs *regs, unsigned int thread_flags, int syscall)
+asmlinkage int
+do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
{
- if (thread_flags & _TIF_SIGPENDING)
- do_signal(regs, syscall);
-
- if (thread_flags & _TIF_NOTIFY_RESUME) {
- clear_thread_flag(TIF_NOTIFY_RESUME);
- tracehook_notify_resume(regs);
- }
+ do {
+ if (likely(thread_flags & _TIF_NEED_RESCHED)) {
+ schedule();
+ } else {
+ if (unlikely(!user_mode(regs)))
+ return 0;
+ local_irq_enable();
+ if (thread_flags & _TIF_SIGPENDING) {
+ int restart = do_signal(regs, syscall);
+ if (unlikely(restart)) {
+ /*
+ * Restart without handlers.
+ * Deal with it without leaving
+ * the kernel space.
+ */
+ return restart;
+ }
+ syscall = 0;
+ } else {
+ clear_thread_flag(TIF_NOTIFY_RESUME);
+ tracehook_notify_resume(regs);
+ }
+ }
+ local_irq_disable();
+ thread_flags = current_thread_info()->flags;
+ } while (thread_flags & _TIF_WORK_MASK);
+ return 0;
}
diff --git a/arch/arm/kernel/signal.h b/arch/arm/kernel/signal.h
index 6fcfe8398aa..5ff067b7c75 100644
--- a/arch/arm/kernel/signal.h
+++ b/arch/arm/kernel/signal.h
@@ -8,7 +8,5 @@
* published by the Free Software Foundation.
*/
#define KERN_SIGRETURN_CODE (CONFIG_VECTORS_BASE + 0x00000500)
-#define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(sigreturn_codes))
extern const unsigned long sigreturn_codes[7];
-extern const unsigned long syscall_restart_code[2];
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index aea74f5bc34..ebd8ad274d7 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -563,7 +563,8 @@ void smp_send_stop(void)
cpumask_copy(&mask, cpu_online_mask);
cpumask_clear_cpu(smp_processor_id(), &mask);
- smp_cross_call(&mask, IPI_CPU_STOP);
+ if (!cpumask_empty(&mask))
+ smp_cross_call(&mask, IPI_CPU_STOP);
/* Wait up to one second for other CPUs to stop */
timeout = USEC_PER_SEC;
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 8b97d739b17..f7945218b8c 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -402,18 +402,10 @@ static int call_undef_hook(struct pt_regs *regs, unsigned int instr)
asmlinkage void __exception do_undefinstr(struct pt_regs *regs)
{
- unsigned int correction = thumb_mode(regs) ? 2 : 4;
unsigned int instr;
siginfo_t info;
void __user *pc;
- /*
- * According to the ARM ARM, PC is 2 or 4 bytes ahead,
- * depending whether we're in Thumb mode or not.
- * Correct this offset.
- */
- regs->ARM_pc -= correction;
-
pc = (void __user *)instruction_pointer(regs);
if (processor_mode(regs) == SVC_MODE) {
@@ -852,8 +844,6 @@ void __init early_trap_init(void *vectors_base)
*/
memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE),
sigreturn_codes, sizeof(sigreturn_codes));
- memcpy((void *)(vectors + KERN_RESTART_CODE - CONFIG_VECTORS_BASE),
- syscall_restart_code, sizeof(syscall_restart_code));
flush_icache_range(vectors, vectors + PAGE_SIZE);
modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
diff --git a/arch/arm/lib/io-acorn.S b/arch/arm/lib/io-acorn.S
index 1b197ea7aab..69719bad674 100644
--- a/arch/arm/lib/io-acorn.S
+++ b/arch/arm/lib/io-acorn.S
@@ -11,13 +11,14 @@
*
*/
#include <linux/linkage.h>
+#include <linux/kern_levels.h>
#include <asm/assembler.h>
.text
.align
.Liosl_warning:
- .ascii "<4>insl/outsl not implemented, called from %08lX\0"
+ .ascii KERN_WARNING "insl/outsl not implemented, called from %08lX\0"
.align
/*
diff --git a/arch/arm/mach-davinci/devices-da8xx.c b/arch/arm/mach-davinci/devices-da8xx.c
index d1624a315c9..783eab6845c 100644
--- a/arch/arm/mach-davinci/devices-da8xx.c
+++ b/arch/arm/mach-davinci/devices-da8xx.c
@@ -546,6 +546,7 @@ static struct lcd_ctrl_config lcd_cfg = {
.sync_edge = 0,
.sync_ctrl = 1,
.raster_order = 0,
+ .fifo_th = 6,
};
struct da8xx_lcdc_platform_data sharp_lcd035q3dg01_pdata = {
diff --git a/arch/arm/mach-exynos/clock-exynos4.c b/arch/arm/mach-exynos/clock-exynos4.c
index 26fe9de35ec..2f51293c187 100644
--- a/arch/arm/mach-exynos/clock-exynos4.c
+++ b/arch/arm/mach-exynos/clock-exynos4.c
@@ -620,10 +620,6 @@ static struct clk exynos4_init_clocks_off[] = {
.enable = exynos4_clk_ip_peril_ctrl,
.ctrlbit = (1 << 27),
}, {
- .name = "fimg2d",
- .enable = exynos4_clk_ip_image_ctrl,
- .ctrlbit = (1 << 0),
- }, {
.name = "mfc",
.devname = "s5p-mfc",
.enable = exynos4_clk_ip_mfc_ctrl,
@@ -819,47 +815,21 @@ static struct clk *exynos4_clkset_mout_g2d0_list[] = {
[1] = &exynos4_clk_sclk_apll.clk,
};
-static struct clksrc_sources exynos4_clkset_mout_g2d0 = {
+struct clksrc_sources exynos4_clkset_mout_g2d0 = {
.sources = exynos4_clkset_mout_g2d0_list,
.nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d0_list),
};
-static struct clksrc_clk exynos4_clk_mout_g2d0 = {
- .clk = {
- .name = "mout_g2d0",
- },
- .sources = &exynos4_clkset_mout_g2d0,
- .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 0, .size = 1 },
-};
-
static struct clk *exynos4_clkset_mout_g2d1_list[] = {
[0] = &exynos4_clk_mout_epll.clk,
[1] = &exynos4_clk_sclk_vpll.clk,
};
-static struct clksrc_sources exynos4_clkset_mout_g2d1 = {
+struct clksrc_sources exynos4_clkset_mout_g2d1 = {
.sources = exynos4_clkset_mout_g2d1_list,
.nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d1_list),
};
-static struct clksrc_clk exynos4_clk_mout_g2d1 = {
- .clk = {
- .name = "mout_g2d1",
- },
- .sources = &exynos4_clkset_mout_g2d1,
- .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 4, .size = 1 },
-};
-
-static struct clk *exynos4_clkset_mout_g2d_list[] = {
- [0] = &exynos4_clk_mout_g2d0.clk,
- [1] = &exynos4_clk_mout_g2d1.clk,
-};
-
-static struct clksrc_sources exynos4_clkset_mout_g2d = {
- .sources = exynos4_clkset_mout_g2d_list,
- .nr_sources = ARRAY_SIZE(exynos4_clkset_mout_g2d_list),
-};
-
static struct clk *exynos4_clkset_mout_mfc0_list[] = {
[0] = &exynos4_clk_mout_mpll.clk,
[1] = &exynos4_clk_sclk_apll.clk,
@@ -1126,13 +1096,6 @@ static struct clksrc_clk exynos4_clksrcs[] = {
.reg_div = { .reg = EXYNOS4_CLKDIV_LCD0, .shift = 0, .size = 4 },
}, {
.clk = {
- .name = "sclk_fimg2d",
- },
- .sources = &exynos4_clkset_mout_g2d,
- .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 8, .size = 1 },
- .reg_div = { .reg = EXYNOS4_CLKDIV_IMAGE, .shift = 0, .size = 4 },
- }, {
- .clk = {
.name = "sclk_mfc",
.devname = "s5p-mfc",
},
diff --git a/arch/arm/mach-exynos/clock-exynos4.h b/arch/arm/mach-exynos/clock-exynos4.h
index 28a11970118..bd12d5f8b63 100644
--- a/arch/arm/mach-exynos/clock-exynos4.h
+++ b/arch/arm/mach-exynos/clock-exynos4.h
@@ -23,6 +23,9 @@ extern struct clksrc_sources exynos4_clkset_group;
extern struct clk *exynos4_clkset_aclk_top_list[];
extern struct clk *exynos4_clkset_group_list[];
+extern struct clksrc_sources exynos4_clkset_mout_g2d0;
+extern struct clksrc_sources exynos4_clkset_mout_g2d1;
+
extern int exynos4_clksrc_mask_fsys_ctrl(struct clk *clk, int enable);
extern int exynos4_clk_ip_fsys_ctrl(struct clk *clk, int enable);
extern int exynos4_clk_ip_lcd1_ctrl(struct clk *clk, int enable);
diff --git a/arch/arm/mach-exynos/clock-exynos4210.c b/arch/arm/mach-exynos/clock-exynos4210.c
index b8689ff60ba..fed4c26e9da 100644
--- a/arch/arm/mach-exynos/clock-exynos4210.c
+++ b/arch/arm/mach-exynos/clock-exynos4210.c
@@ -48,6 +48,32 @@ static struct clksrc_clk *sysclks[] = {
/* nothing here yet */
};
+static struct clksrc_clk exynos4210_clk_mout_g2d0 = {
+ .clk = {
+ .name = "mout_g2d0",
+ },
+ .sources = &exynos4_clkset_mout_g2d0,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 0, .size = 1 },
+};
+
+static struct clksrc_clk exynos4210_clk_mout_g2d1 = {
+ .clk = {
+ .name = "mout_g2d1",
+ },
+ .sources = &exynos4_clkset_mout_g2d1,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 4, .size = 1 },
+};
+
+static struct clk *exynos4210_clkset_mout_g2d_list[] = {
+ [0] = &exynos4210_clk_mout_g2d0.clk,
+ [1] = &exynos4210_clk_mout_g2d1.clk,
+};
+
+static struct clksrc_sources exynos4210_clkset_mout_g2d = {
+ .sources = exynos4210_clkset_mout_g2d_list,
+ .nr_sources = ARRAY_SIZE(exynos4210_clkset_mout_g2d_list),
+};
+
static int exynos4_clksrc_mask_lcd1_ctrl(struct clk *clk, int enable)
{
return s5p_gatectrl(EXYNOS4210_CLKSRC_MASK_LCD1, clk, enable);
@@ -74,6 +100,13 @@ static struct clksrc_clk clksrcs[] = {
.sources = &exynos4_clkset_group,
.reg_src = { .reg = EXYNOS4210_CLKSRC_LCD1, .shift = 0, .size = 4 },
.reg_div = { .reg = EXYNOS4210_CLKDIV_LCD1, .shift = 0, .size = 4 },
+ }, {
+ .clk = {
+ .name = "sclk_fimg2d",
+ },
+ .sources = &exynos4210_clkset_mout_g2d,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_IMAGE, .shift = 8, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_IMAGE, .shift = 0, .size = 4 },
},
};
@@ -105,6 +138,10 @@ static struct clk init_clocks_off[] = {
.devname = SYSMMU_CLOCK_DEVNAME(fimd1, 11),
.enable = exynos4_clk_ip_lcd1_ctrl,
.ctrlbit = (1 << 4),
+ }, {
+ .name = "fimg2d",
+ .enable = exynos4_clk_ip_image_ctrl,
+ .ctrlbit = (1 << 0),
},
};
diff --git a/arch/arm/mach-exynos/clock-exynos4212.c b/arch/arm/mach-exynos/clock-exynos4212.c
index da397d21bbc..8fba0b5fb8a 100644
--- a/arch/arm/mach-exynos/clock-exynos4212.c
+++ b/arch/arm/mach-exynos/clock-exynos4212.c
@@ -68,12 +68,45 @@ static struct clksrc_clk clk_mout_mpll_user = {
.reg_src = { .reg = EXYNOS4_CLKSRC_CPU, .shift = 24, .size = 1 },
};
+static struct clksrc_clk exynos4x12_clk_mout_g2d0 = {
+ .clk = {
+ .name = "mout_g2d0",
+ },
+ .sources = &exynos4_clkset_mout_g2d0,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 20, .size = 1 },
+};
+
+static struct clksrc_clk exynos4x12_clk_mout_g2d1 = {
+ .clk = {
+ .name = "mout_g2d1",
+ },
+ .sources = &exynos4_clkset_mout_g2d1,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 24, .size = 1 },
+};
+
+static struct clk *exynos4x12_clkset_mout_g2d_list[] = {
+ [0] = &exynos4x12_clk_mout_g2d0.clk,
+ [1] = &exynos4x12_clk_mout_g2d1.clk,
+};
+
+static struct clksrc_sources exynos4x12_clkset_mout_g2d = {
+ .sources = exynos4x12_clkset_mout_g2d_list,
+ .nr_sources = ARRAY_SIZE(exynos4x12_clkset_mout_g2d_list),
+};
+
static struct clksrc_clk *sysclks[] = {
&clk_mout_mpll_user,
};
static struct clksrc_clk clksrcs[] = {
- /* nothing here yet */
+ {
+ .clk = {
+ .name = "sclk_fimg2d",
+ },
+ .sources = &exynos4x12_clkset_mout_g2d,
+ .reg_src = { .reg = EXYNOS4_CLKSRC_DMC, .shift = 28, .size = 1 },
+ .reg_div = { .reg = EXYNOS4_CLKDIV_DMC1, .shift = 0, .size = 4 },
+ },
};
static struct clk init_clocks_off[] = {
@@ -102,7 +135,11 @@ static struct clk init_clocks_off[] = {
.devname = "exynos-fimc-lite.1",
.enable = exynos4212_clk_ip_isp0_ctrl,
.ctrlbit = (1 << 3),
- }
+ }, {
+ .name = "fimg2d",
+ .enable = exynos4_clk_ip_dmc_ctrl,
+ .ctrlbit = (1 << 23),
+ },
};
#ifdef CONFIG_PM_SLEEP
diff --git a/arch/arm/mach-exynos/mach-nuri.c b/arch/arm/mach-exynos/mach-nuri.c
index f98a83a81ce..ea785fcaf6c 100644
--- a/arch/arm/mach-exynos/mach-nuri.c
+++ b/arch/arm/mach-exynos/mach-nuri.c
@@ -1066,12 +1066,8 @@ static struct platform_device nuri_max8903_device = {
static void __init nuri_power_init(void)
{
int gpio;
- int irq_base = IRQ_GPIO_END + 1;
int ta_en = 0;
- nuri_max8997_pdata.irq_base = irq_base;
- irq_base += MAX8997_IRQ_NR;
-
gpio = EXYNOS4_GPX0(7);
gpio_request(gpio, "AP_PMIC_IRQ");
s3c_gpio_cfgpin(gpio, S3C_GPIO_SFN(0xf));
diff --git a/arch/arm/mach-exynos/mach-origen.c b/arch/arm/mach-exynos/mach-origen.c
index 5a12dc26f49..5ca80307d6d 100644
--- a/arch/arm/mach-exynos/mach-origen.c
+++ b/arch/arm/mach-exynos/mach-origen.c
@@ -426,7 +426,6 @@ static struct max8997_platform_data __initdata origen_max8997_pdata = {
.buck1_gpiodvs = false,
.buck2_gpiodvs = false,
.buck5_gpiodvs = false,
- .irq_base = IRQ_GPIO_END + 1,
.ignore_gpiodvs_side_effect = true,
.buck125_default_idx = 0x0,
diff --git a/arch/arm/mach-netx/fb.c b/arch/arm/mach-netx/fb.c
index 2cdf6ef69be..d122ee6ab99 100644
--- a/arch/arm/mach-netx/fb.c
+++ b/arch/arm/mach-netx/fb.c
@@ -69,29 +69,6 @@ void netx_clcd_remove(struct clcd_fb *fb)
fb->fb.screen_base, fb->fb.fix.smem_start);
}
-void clk_disable(struct clk *clk)
-{
-}
-
-int clk_set_rate(struct clk *clk, unsigned long rate)
-{
- return 0;
-}
-
-int clk_enable(struct clk *clk)
-{
- return 0;
-}
-
-struct clk *clk_get(struct device *dev, const char *id)
-{
- return dev && strcmp(dev_name(dev), "fb") == 0 ? NULL : ERR_PTR(-ENOENT);
-}
-
-void clk_put(struct clk *clk)
-{
-}
-
static AMBA_AHB_DEVICE(fb, "fb", 0, 0x00104000, { NETX_IRQ_LCD }, NULL);
int netx_fb_init(struct clcd_board *board, struct clcd_panel *panel)
diff --git a/arch/arm/mach-omap1/board-h2-mmc.c b/arch/arm/mach-omap1/board-h2-mmc.c
index da0e37d4082..e1362ce4849 100644
--- a/arch/arm/mach-omap1/board-h2-mmc.c
+++ b/arch/arm/mach-omap1/board-h2-mmc.c
@@ -54,7 +54,6 @@ static struct omap_mmc_platform_data mmc1_data = {
.nr_slots = 1,
.init = mmc_late_init,
.cleanup = mmc_cleanup,
- .dma_mask = 0xffffffff,
.slots[0] = {
.set_power = mmc_set_power,
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
diff --git a/arch/arm/mach-omap1/board-h3-mmc.c b/arch/arm/mach-omap1/board-h3-mmc.c
index f8242aa9b76..c74daace8cd 100644
--- a/arch/arm/mach-omap1/board-h3-mmc.c
+++ b/arch/arm/mach-omap1/board-h3-mmc.c
@@ -36,7 +36,6 @@ static int mmc_set_power(struct device *dev, int slot, int power_on,
*/
static struct omap_mmc_platform_data mmc1_data = {
.nr_slots = 1,
- .dma_mask = 0xffffffff,
.slots[0] = {
.set_power = mmc_set_power,
.ocr_mask = MMC_VDD_32_33 | MMC_VDD_33_34,
diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
index 4007a372481..2c0ca8fc338 100644
--- a/arch/arm/mach-omap1/board-nokia770.c
+++ b/arch/arm/mach-omap1/board-nokia770.c
@@ -185,7 +185,6 @@ static int nokia770_mmc_get_cover_state(struct device *dev, int slot)
static struct omap_mmc_platform_data nokia770_mmc2_data = {
.nr_slots = 1,
- .dma_mask = 0xffffffff,
.max_freq = 12000000,
.slots[0] = {
.set_power = nokia770_mmc_set_power,
diff --git a/arch/arm/mach-omap1/board-palmz71.c b/arch/arm/mach-omap1/board-palmz71.c
index cc71a26723e..355980321c2 100644
--- a/arch/arm/mach-omap1/board-palmz71.c
+++ b/arch/arm/mach-omap1/board-palmz71.c
@@ -288,8 +288,7 @@ palmz71_gpio_setup(int early)
}
gpio_direction_input(PALMZ71_USBDETECT_GPIO);
if (request_irq(gpio_to_irq(PALMZ71_USBDETECT_GPIO),
- palmz71_powercable, IRQF_SAMPLE_RANDOM,
- "palmz71-cable", NULL))
+ palmz71_powercable, 0, "palmz71-cable", NULL))
printk(KERN_ERR
"IRQ request for power cable failed!\n");
palmz71_powercable(gpio_to_irq(PALMZ71_USBDETECT_GPIO), NULL);
diff --git a/arch/arm/mach-omap2/board-n8x0.c b/arch/arm/mach-omap2/board-n8x0.c
index 2c5d0ed7528..677357ff61a 100644
--- a/arch/arm/mach-omap2/board-n8x0.c
+++ b/arch/arm/mach-omap2/board-n8x0.c
@@ -468,7 +468,6 @@ static struct omap_mmc_platform_data mmc1_data = {
.cleanup = n8x0_mmc_cleanup,
.shutdown = n8x0_mmc_shutdown,
.max_freq = 24000000,
- .dma_mask = 0xffffffff,
.slots[0] = {
.wires = 4,
.set_power = n8x0_mmc_set_power,
diff --git a/arch/arm/mach-omap2/display.c b/arch/arm/mach-omap2/display.c
index 5fb47a14f4b..af1ed7d24a1 100644
--- a/arch/arm/mach-omap2/display.c
+++ b/arch/arm/mach-omap2/display.c
@@ -37,6 +37,7 @@
#define DISPC_CONTROL 0x0040
#define DISPC_CONTROL2 0x0238
+#define DISPC_CONTROL3 0x0848
#define DISPC_IRQSTATUS 0x0018
#define DSS_SYSCONFIG 0x10
@@ -52,6 +53,7 @@
#define EVSYNC_EVEN_IRQ_SHIFT 2
#define EVSYNC_ODD_IRQ_SHIFT 3
#define FRAMEDONE2_IRQ_SHIFT 22
+#define FRAMEDONE3_IRQ_SHIFT 30
#define FRAMEDONETV_IRQ_SHIFT 24
/*
@@ -376,7 +378,7 @@ int __init omap_display_init(struct omap_dss_board_info *board_data)
static void dispc_disable_outputs(void)
{
u32 v, irq_mask = 0;
- bool lcd_en, digit_en, lcd2_en = false;
+ bool lcd_en, digit_en, lcd2_en = false, lcd3_en = false;
int i;
struct omap_dss_dispc_dev_attr *da;
struct omap_hwmod *oh;
@@ -405,7 +407,13 @@ static void dispc_disable_outputs(void)
lcd2_en = v & LCD_EN_MASK;
}
- if (!(lcd_en | digit_en | lcd2_en))
+ /* store value of LCDENABLE for LCD3 */
+ if (da->manager_count > 3) {
+ v = omap_hwmod_read(oh, DISPC_CONTROL3);
+ lcd3_en = v & LCD_EN_MASK;
+ }
+
+ if (!(lcd_en | digit_en | lcd2_en | lcd3_en))
return; /* no managers currently enabled */
/*
@@ -426,10 +434,12 @@ static void dispc_disable_outputs(void)
if (lcd2_en)
irq_mask |= 1 << FRAMEDONE2_IRQ_SHIFT;
+ if (lcd3_en)
+ irq_mask |= 1 << FRAMEDONE3_IRQ_SHIFT;
/*
* clear any previous FRAMEDONE, FRAMEDONETV,
- * EVSYNC_EVEN/ODD or FRAMEDONE2 interrupts
+ * EVSYNC_EVEN/ODD, FRAMEDONE2 or FRAMEDONE3 interrupts
*/
omap_hwmod_write(irq_mask, oh, DISPC_IRQSTATUS);
@@ -445,12 +455,19 @@ static void dispc_disable_outputs(void)
omap_hwmod_write(v, oh, DISPC_CONTROL2);
}
+ /* disable LCD3 manager */
+ if (da->manager_count > 3) {
+ v = omap_hwmod_read(oh, DISPC_CONTROL3);
+ v &= ~LCD_EN_MASK;
+ omap_hwmod_write(v, oh, DISPC_CONTROL3);
+ }
+
i = 0;
while ((omap_hwmod_read(oh, DISPC_IRQSTATUS) & irq_mask) !=
irq_mask) {
i++;
if (i > FRAMEDONE_IRQ_TIMEOUT) {
- pr_err("didn't get FRAMEDONE1/2 or TV interrupt\n");
+ pr_err("didn't get FRAMEDONE1/2/3 or TV interrupt\n");
break;
}
mdelay(1);
diff --git a/arch/arm/mach-omap2/hsmmc.c b/arch/arm/mach-omap2/hsmmc.c
index be697d4e084..a9675d8d182 100644
--- a/arch/arm/mach-omap2/hsmmc.c
+++ b/arch/arm/mach-omap2/hsmmc.c
@@ -315,7 +315,6 @@ static int __init omap_hsmmc_pdata_init(struct omap2_hsmmc_info *c,
mmc->slots[0].caps = c->caps;
mmc->slots[0].pm_caps = c->pm_caps;
mmc->slots[0].internal_clock = !c->ext_clock;
- mmc->dma_mask = 0xffffffff;
mmc->max_freq = c->max_freq;
if (cpu_is_omap44xx())
mmc->reg_offset = OMAP4_MMC_REG_OFFSET;
diff --git a/arch/arm/mach-pxa/eseries.h b/arch/arm/mach-pxa/eseries.h
deleted file mode 100644
index b96949dd5ad..00000000000
--- a/arch/arm/mach-pxa/eseries.h
+++ /dev/null
@@ -1,14 +0,0 @@
-void __init eseries_fixup(struct tag *tags, char **cmdline, struct meminfo *mi);
-
-extern struct pxa2xx_udc_mach_info e7xx_udc_mach_info;
-extern struct pxaficp_platform_data e7xx_ficp_platform_data;
-extern int e7xx_irda_init(void);
-
-extern int eseries_tmio_enable(struct platform_device *dev);
-extern int eseries_tmio_disable(struct platform_device *dev);
-extern int eseries_tmio_suspend(struct platform_device *dev);
-extern int eseries_tmio_resume(struct platform_device *dev);
-extern void eseries_get_tmio_gpios(void);
-extern struct resource eseries_tmio_resources[];
-extern struct platform_device e300_tc6387xb_device;
-
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index d3de84b0dcb..e6311988add 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -296,27 +296,11 @@ static struct asic3_led asic3_leds[ASIC3_NUM_LEDS] = {
static struct resource asic3_resources[] = {
/* GPIO part */
- [0] = {
- .start = ASIC3_PHYS,
- .end = ASIC3_PHYS + ASIC3_MAP_SIZE_16BIT - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = PXA_GPIO_TO_IRQ(GPIO12_HX4700_ASIC3_IRQ),
- .end = PXA_GPIO_TO_IRQ(GPIO12_HX4700_ASIC3_IRQ),
- .flags = IORESOURCE_IRQ,
- },
+ [0] = DEFINE_RES_MEM(ASIC3_PHYS, ASIC3_MAP_SIZE_16BIT),
+ [1] = DEFINE_RES_IRQ(PXA_GPIO_TO_IRQ(GPIO12_HX4700_ASIC3_IRQ)),
/* SD part */
- [2] = {
- .start = ASIC3_SD_PHYS,
- .end = ASIC3_SD_PHYS + ASIC3_MAP_SIZE_16BIT - 1,
- .flags = IORESOURCE_MEM,
- },
- [3] = {
- .start = PXA_GPIO_TO_IRQ(GPIO66_HX4700_ASIC3_nSDIO_IRQ),
- .end = PXA_GPIO_TO_IRQ(GPIO66_HX4700_ASIC3_nSDIO_IRQ),
- .flags = IORESOURCE_IRQ,
- },
+ [2] = DEFINE_RES_MEM(ASIC3_SD_PHYS, ASIC3_MAP_SIZE_16BIT),
+ [3] = DEFINE_RES_IRQ(PXA_GPIO_TO_IRQ(GPIO66_HX4700_ASIC3_nSDIO_IRQ)),
};
static struct asic3_platform_data asic3_platform_data = {
@@ -343,11 +327,7 @@ static struct platform_device asic3 = {
*/
static struct resource egpio_resources[] = {
- [0] = {
- .start = PXA_CS5_PHYS,
- .end = PXA_CS5_PHYS + 0x4 - 1,
- .flags = IORESOURCE_MEM,
- },
+ [0] = DEFINE_RES_MEM(PXA_CS5_PHYS, 0x4),
};
static struct htc_egpio_chip egpio_chips[] = {
@@ -537,11 +517,7 @@ static struct w100fb_mach_info w3220_info = {
};
static struct resource w3220_resources[] = {
- [0] = {
- .start = ATI_W3220_PHYS,
- .end = ATI_W3220_PHYS + 0x00ffffff,
- .flags = IORESOURCE_MEM,
- },
+ [0] = DEFINE_RES_MEM(ATI_W3220_PHYS, SZ_16M),
};
static struct platform_device w3220 = {
@@ -683,20 +659,12 @@ static struct pda_power_pdata power_supply_info = {
};
static struct resource power_supply_resources[] = {
- [0] = {
- .name = "ac",
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
- IORESOURCE_IRQ_LOWEDGE,
- .start = PXA_GPIO_TO_IRQ(GPIOD9_nAC_IN),
- .end = PXA_GPIO_TO_IRQ(GPIOD9_nAC_IN),
- },
- [1] = {
- .name = "usb",
- .flags = IORESOURCE_IRQ | IORESOURCE_IRQ_HIGHEDGE |
- IORESOURCE_IRQ_LOWEDGE,
- .start = PXA_GPIO_TO_IRQ(GPIOD14_nUSBC_DETECT),
- .end = PXA_GPIO_TO_IRQ(GPIOD14_nUSBC_DETECT),
- },
+ [0] = DEFINE_RES_NAMED(PXA_GPIO_TO_IRQ(GPIOD9_nAC_IN), 1, "ac",
+ IORESOURCE_IRQ |
+ IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE),
+ [1] = DEFINE_RES_NAMED(PXA_GPIO_TO_IRQ(GPIOD14_nUSBC_DETECT), 1, "usb",
+ IORESOURCE_IRQ |
+ IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE),
};
static struct platform_device power_supply = {
diff --git a/arch/arm/mach-pxa/lubbock.c b/arch/arm/mach-pxa/lubbock.c
index 6bb3f47b1f1..0ca0db78790 100644
--- a/arch/arm/mach-pxa/lubbock.c
+++ b/arch/arm/mach-pxa/lubbock.c
@@ -456,7 +456,7 @@ static int lubbock_mci_init(struct device *dev,
init_timer(&mmc_timer);
mmc_timer.data = (unsigned long) data;
return request_irq(LUBBOCK_SD_IRQ, lubbock_detect_int,
- IRQF_SAMPLE_RANDOM, "lubbock-sd-detect", data);
+ 0, "lubbock-sd-detect", data);
}
static int lubbock_mci_get_ro(struct device *dev)
diff --git a/arch/arm/mach-pxa/magician.c b/arch/arm/mach-pxa/magician.c
index 2db697cd2b4..39561dcf65f 100644
--- a/arch/arm/mach-pxa/magician.c
+++ b/arch/arm/mach-pxa/magician.c
@@ -633,9 +633,8 @@ static struct platform_device bq24022 = {
static int magician_mci_init(struct device *dev,
irq_handler_t detect_irq, void *data)
{
- return request_irq(IRQ_MAGICIAN_SD, detect_irq,
- IRQF_DISABLED | IRQF_SAMPLE_RANDOM,
- "mmc card detect", data);
+ return request_irq(IRQ_MAGICIAN_SD, detect_irq, IRQF_DISABLED,
+ "mmc card detect", data);
}
static void magician_mci_exit(struct device *dev, void *data)
diff --git a/arch/arm/mach-pxa/trizeps4.c b/arch/arm/mach-pxa/trizeps4.c
index 2b6ac00b2cd..166dd32cc1d 100644
--- a/arch/arm/mach-pxa/trizeps4.c
+++ b/arch/arm/mach-pxa/trizeps4.c
@@ -332,8 +332,8 @@ static int trizeps4_mci_init(struct device *dev, irq_handler_t mci_detect_int,
int err;
err = request_irq(TRIZEPS4_MMC_IRQ, mci_detect_int,
- IRQF_DISABLED | IRQF_TRIGGER_RISING | IRQF_SAMPLE_RANDOM,
- "MMC card detect", data);
+ IRQF_DISABLED | IRQF_TRIGGER_RISING,
+ "MMC card detect", data);
if (err) {
printk(KERN_ERR "trizeps4_mci_init: MMC/SD: can't request"
"MMC card detect IRQ\n");
diff --git a/arch/arm/mach-s3c64xx/include/mach/pm-core.h b/arch/arm/mach-s3c64xx/include/mach/pm-core.h
index fcf3dcabb69..c0537f40a3d 100644
--- a/arch/arm/mach-s3c64xx/include/mach/pm-core.h
+++ b/arch/arm/mach-s3c64xx/include/mach/pm-core.h
@@ -12,6 +12,9 @@
* published by the Free Software Foundation.
*/
+#ifndef __MACH_S3C64XX_PM_CORE_H
+#define __MACH_S3C64XX_PM_CORE_H __FILE__
+
#include <mach/regs-gpio.h>
static inline void s3c_pm_debug_init_uart(void)
@@ -113,3 +116,4 @@ static inline void samsung_pm_saved_gpios(void)
__raw_writel(S3C64XX_SLPEN_USE_xSLP, S3C64XX_SLPEN);
}
+#endif /* __MACH_S3C64XX_PM_CORE_H */
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index df33909205e..4cacc2d22fb 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -19,6 +19,7 @@ config ARCH_SH7372
select CPU_V7
select SH_CLK_CPG
select ARCH_WANT_OPTIONAL_GPIOLIB
+ select ARM_CPU_SUSPEND if PM || CPU_IDLE
config ARCH_SH73A0
bool "SH-Mobile AG5 (R8A73A00)"
@@ -58,6 +59,7 @@ config MACH_G4EVM
bool "G4EVM board"
depends on ARCH_SH7377
select ARCH_REQUIRE_GPIOLIB
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
config MACH_AP4EVB
bool "AP4EVB board"
@@ -65,6 +67,7 @@ config MACH_AP4EVB
select ARCH_REQUIRE_GPIOLIB
select SH_LCD_MIPI_DSI
select SND_SOC_AK4642 if SND_SIMPLE_CARD
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
choice
prompt "AP4EVB LCD panel selection"
@@ -83,6 +86,7 @@ config MACH_AG5EVM
bool "AG5EVM board"
select ARCH_REQUIRE_GPIOLIB
select SH_LCD_MIPI_DSI
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
depends on ARCH_SH73A0
config MACH_MACKEREL
@@ -90,15 +94,18 @@ config MACH_MACKEREL
depends on ARCH_SH7372
select ARCH_REQUIRE_GPIOLIB
select SND_SOC_AK4642 if SND_SIMPLE_CARD
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
config MACH_KOTA2
bool "KOTA2 board"
select ARCH_REQUIRE_GPIOLIB
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
depends on ARCH_SH73A0
config MACH_BONITO
bool "bonito board"
select ARCH_REQUIRE_GPIOLIB
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
depends on ARCH_R8A7740
config MACH_ARMADILLO800EVA
@@ -106,22 +113,28 @@ config MACH_ARMADILLO800EVA
depends on ARCH_R8A7740
select ARCH_REQUIRE_GPIOLIB
select USE_OF
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
+ select SND_SOC_WM8978 if SND_SIMPLE_CARD
config MACH_MARZEN
bool "MARZEN board"
depends on ARCH_R8A7779
select ARCH_REQUIRE_GPIOLIB
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
config MACH_KZM9D
bool "KZM9D board"
depends on ARCH_EMEV2
select USE_OF
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
config MACH_KZM9G
bool "KZM-A9-GT board"
depends on ARCH_SH73A0
select ARCH_REQUIRE_GPIOLIB
select USE_OF
+ select SND_SOC_AK4642 if SND_SIMPLE_CARD
+ select REGULATOR_FIXED_VOLTAGE if REGULATOR
comment "SH-Mobile System Configuration"
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index 8aa1962c22a..0df5ae6740c 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -39,7 +39,9 @@ obj-$(CONFIG_ARCH_R8A7740) += entry-intc.o
# PM objects
obj-$(CONFIG_SUSPEND) += suspend.o
obj-$(CONFIG_CPU_IDLE) += cpuidle.o
+obj-$(CONFIG_ARCH_SHMOBILE) += pm-rmobile.o
obj-$(CONFIG_ARCH_SH7372) += pm-sh7372.o sleep-sh7372.o
+obj-$(CONFIG_ARCH_R8A7740) += pm-r8a7740.o
obj-$(CONFIG_ARCH_R8A7779) += pm-r8a7779.o
# Board objects
diff --git a/arch/arm/mach-shmobile/board-ag5evm.c b/arch/arm/mach-shmobile/board-ag5evm.c
index 5a6f22f05e9..d82c010fdfc 100644
--- a/arch/arm/mach-shmobile/board-ag5evm.c
+++ b/arch/arm/mach-shmobile/board-ag5evm.c
@@ -27,6 +27,8 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/dma-mapping.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
#include <linux/serial_sci.h>
#include <linux/smsc911x.h>
#include <linux/gpio.h>
@@ -52,6 +54,12 @@
#include <asm/hardware/cache-l2x0.h>
#include <asm/traps.h>
+/* Dummy supplies, where voltage doesn't matter */
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+};
+
static struct resource smsc9220_resources[] = {
[0] = {
.start = 0x14000000,
@@ -142,6 +150,13 @@ static struct platform_device fsi_device = {
.resource = fsi_resources,
};
+/* Fixed 1.8V regulator to be used by MMCIF */
+static struct regulator_consumer_supply fixed1v8_power_consumers[] =
+{
+ REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"),
+};
+
static struct resource sh_mmcif_resources[] = {
[0] = {
.name = "MMCIF",
@@ -364,6 +379,13 @@ static struct platform_device mipidsi0_device = {
},
};
+/* Fixed 2.8V regulators to be used by SDHI0 */
+static struct regulator_consumer_supply fixed2v8_power_consumers[] =
+{
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
+};
+
/* SDHI0 */
static struct sh_mobile_sdhi_info sdhi0_info = {
.dma_slave_tx = SHDMA_SLAVE_SDHI0_TX,
@@ -408,8 +430,57 @@ static struct platform_device sdhi0_device = {
},
};
-void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state)
+/* Fixed 3.3V regulator to be used by SDHI1 */
+static struct regulator_consumer_supply cn4_power_consumers[] =
{
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"),
+};
+
+static struct regulator_init_data cn4_power_init_data = {
+ .constraints = {
+ .valid_ops_mask = REGULATOR_CHANGE_STATUS,
+ },
+ .num_consumer_supplies = ARRAY_SIZE(cn4_power_consumers),
+ .consumer_supplies = cn4_power_consumers,
+};
+
+static struct fixed_voltage_config cn4_power_info = {
+ .supply_name = "CN4 SD/MMC Vdd",
+ .microvolts = 3300000,
+ .gpio = GPIO_PORT114,
+ .enable_high = 1,
+ .init_data = &cn4_power_init_data,
+};
+
+static struct platform_device cn4_power = {
+ .name = "reg-fixed-voltage",
+ .id = 2,
+ .dev = {
+ .platform_data = &cn4_power_info,
+ },
+};
+
+static void ag5evm_sdhi1_set_pwr(struct platform_device *pdev, int state)
+{
+ static int power_gpio = -EINVAL;
+
+ if (power_gpio < 0) {
+ int ret = gpio_request(GPIO_PORT114, "sdhi1_power");
+ if (!ret) {
+ power_gpio = GPIO_PORT114;
+ gpio_direction_output(power_gpio, 0);
+ }
+ }
+
+ /*
+ * If requesting the GPIO above failed, it means, that the regulator got
+ * probed and grabbed the GPIO, but we don't know, whether the sdhi
+ * driver already uses the regulator. If it doesn't, we have to toggle
+ * the GPIO ourselves, even though it is now owned by the fixed
+ * regulator driver. We have to live with the race in case the driver
+ * gets unloaded and the GPIO freed between these two steps.
+ */
gpio_set_value(GPIO_PORT114, state);
}
@@ -455,6 +526,7 @@ static struct platform_device sdhi1_device = {
};
static struct platform_device *ag5evm_devices[] __initdata = {
+ &cn4_power,
&eth_device,
&keysc_device,
&fsi_device,
@@ -468,6 +540,12 @@ static struct platform_device *ag5evm_devices[] __initdata = {
static void __init ag5evm_init(void)
{
+ regulator_register_always_on(0, "fixed-1.8V", fixed1v8_power_consumers,
+ ARRAY_SIZE(fixed1v8_power_consumers), 1800000);
+ regulator_register_always_on(1, "fixed-2.8V", fixed2v8_power_consumers,
+ ARRAY_SIZE(fixed2v8_power_consumers), 3300000);
+ regulator_register_fixed(3, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
sh73a0_pinmux_init();
/* enable SCIFA2 */
@@ -562,8 +640,6 @@ static void __init ag5evm_init(void)
gpio_request(GPIO_FN_SDHID1_2_PU, NULL);
gpio_request(GPIO_FN_SDHID1_1_PU, NULL);
gpio_request(GPIO_FN_SDHID1_0_PU, NULL);
- gpio_request(GPIO_PORT114, "sdhi1_power");
- gpio_direction_output(GPIO_PORT114, 0);
#ifdef CONFIG_CACHE_L2X0
/* Shared attribute override enable, 64K*8way */
diff --git a/arch/arm/mach-shmobile/board-ap4evb.c b/arch/arm/mach-shmobile/board-ap4evb.c
index ace60246a5d..f172ca85905 100644
--- a/arch/arm/mach-shmobile/board-ap4evb.c
+++ b/arch/arm/mach-shmobile/board-ap4evb.c
@@ -34,6 +34,8 @@
#include <linux/i2c.h>
#include <linux/i2c/tsc2007.h>
#include <linux/io.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
#include <linux/smsc911x.h>
#include <linux/sh_intc.h>
#include <linux/sh_clk.h>
@@ -159,6 +161,27 @@
* CN12: 3.3v
*/
+/* Dummy supplies, where voltage doesn't matter */
+static struct regulator_consumer_supply fixed1v8_power_consumers[] =
+{
+ /* J22 default position: 1.8V */
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"),
+ REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"),
+};
+
+static struct regulator_consumer_supply fixed3v3_power_consumers[] =
+{
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
+};
+
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+};
+
/* MTD */
static struct mtd_partition nor_flash_partitions[] = {
{
@@ -1138,21 +1161,6 @@ static void __init fsi_init_pm_clock(void)
clk_put(fsia_ick);
}
-/*
- * FIXME !!
- *
- * gpio_no_direction
- * are quick_hack.
- *
- * current gpio frame work doesn't have
- * the method to control only pull up/down/free.
- * this function should be replaced by correct gpio function
- */
-static void __init gpio_no_direction(u32 addr)
-{
- __raw_writeb(0x00, addr);
-}
-
/* TouchScreen */
#ifdef CONFIG_AP4EVB_QHD
# define GPIO_TSC_IRQ GPIO_FN_IRQ28_123
@@ -1224,6 +1232,12 @@ static void __init ap4evb_init(void)
u32 srcr4;
struct clk *clk;
+ regulator_register_always_on(0, "fixed-1.8V", fixed1v8_power_consumers,
+ ARRAY_SIZE(fixed1v8_power_consumers), 1800000);
+ regulator_register_always_on(1, "fixed-3.3V", fixed3v3_power_consumers,
+ ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
+ regulator_register_fixed(2, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
/* External clock source */
clk_set_rate(&sh7372_dv_clki_clk, 27000000);
@@ -1302,8 +1316,8 @@ static void __init ap4evb_init(void)
gpio_request(GPIO_PORT9, NULL);
gpio_request(GPIO_PORT10, NULL);
- gpio_no_direction(GPIO_PORT9CR); /* FSIAOBT needs no direction */
- gpio_no_direction(GPIO_PORT10CR); /* FSIAOLR needs no direction */
+ gpio_direction_none(GPIO_PORT9CR); /* FSIAOBT needs no direction */
+ gpio_direction_none(GPIO_PORT10CR); /* FSIAOLR needs no direction */
/* card detect pin for MMC slot (CN7) */
gpio_request(GPIO_PORT41, NULL);
@@ -1447,14 +1461,14 @@ static void __init ap4evb_init(void)
platform_add_devices(ap4evb_devices, ARRAY_SIZE(ap4evb_devices));
- sh7372_add_device_to_domain(&sh7372_a4lc, &lcdc1_device);
- sh7372_add_device_to_domain(&sh7372_a4lc, &lcdc_device);
- sh7372_add_device_to_domain(&sh7372_a4mp, &fsi_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4lc, &lcdc1_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4lc, &lcdc_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4mp, &fsi_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &sh_mmcif_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi0_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi1_device);
- sh7372_add_device_to_domain(&sh7372_a4r, &ceu_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sh_mmcif_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi0_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi1_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4r, &ceu_device);
hdmi_init_pm_clock();
fsi_init_pm_clock();
diff --git a/arch/arm/mach-shmobile/board-armadillo800eva.c b/arch/arm/mach-shmobile/board-armadillo800eva.c
index 9bd135531d7..cf10f92856d 100644
--- a/arch/arm/mach-shmobile/board-armadillo800eva.c
+++ b/arch/arm/mach-shmobile/board-armadillo800eva.c
@@ -28,6 +28,8 @@
#include <linux/platform_device.h>
#include <linux/gpio.h>
#include <linux/gpio_keys.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
#include <linux/sh_eth.h>
#include <linux/videodev2.h>
#include <linux/usb/renesas_usbhs.h>
@@ -37,14 +39,20 @@
#include <linux/mmc/sh_mobile_sdhi.h>
#include <mach/common.h>
#include <mach/irqs.h>
+#include <mach/r8a7740.h>
+#include <media/mt9t112.h>
+#include <media/sh_mobile_ceu.h>
+#include <media/soc_camera.h>
#include <asm/page.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/mach/time.h>
#include <asm/hardware/cache-l2x0.h>
-#include <mach/r8a7740.h>
#include <video/sh_mobile_lcdc.h>
+#include <video/sh_mobile_hdmi.h>
+#include <sound/sh_fsi.h>
+#include <sound/simple_card.h>
/*
* CON1 Camera Module
@@ -108,6 +116,14 @@
*/
/*
+ * FSI-WM8978
+ *
+ * this command is required when playback.
+ *
+ * # amixer set "Headphone" 50
+ */
+
+/*
* USB function
*
* When you use USB Function,
@@ -117,14 +133,8 @@
* These are a little bit complex.
* see
* usbhsf_power_ctrl()
- *
- * CAUTION
- *
- * It uses autonomy mode for USB hotplug at this point
- * (= usbhs_private.platform_callback.get_vbus is NULL),
- * since we don't know what's happen on PM control
- * on this workaround.
*/
+#define IRQ7 evt2irq(0x02e0)
#define USBCR1 0xe605810a
#define USBH 0xC6700000
#define USBH_USBCTR 0x10834
@@ -204,6 +214,20 @@ static void usbhsf_power_ctrl(struct platform_device *pdev,
}
}
+static int usbhsf_get_vbus(struct platform_device *pdev)
+{
+ return gpio_get_value(GPIO_PORT209);
+}
+
+static irqreturn_t usbhsf_interrupt(int irq, void *data)
+{
+ struct platform_device *pdev = data;
+
+ renesas_usbhs_call_notify_hotplug(pdev);
+
+ return IRQ_HANDLED;
+}
+
static void usbhsf_hardware_exit(struct platform_device *pdev)
{
struct usbhsf_private *priv = usbhsf_get_priv(pdev);
@@ -227,11 +251,14 @@ static void usbhsf_hardware_exit(struct platform_device *pdev)
priv->host = NULL;
priv->func = NULL;
priv->usbh_base = NULL;
+
+ free_irq(IRQ7, pdev);
}
static int usbhsf_hardware_init(struct platform_device *pdev)
{
struct usbhsf_private *priv = usbhsf_get_priv(pdev);
+ int ret;
priv->phy = clk_get(&pdev->dev, "phy");
priv->usb24 = clk_get(&pdev->dev, "usb24");
@@ -251,6 +278,14 @@ static int usbhsf_hardware_init(struct platform_device *pdev)
return -EIO;
}
+ ret = request_irq(IRQ7, usbhsf_interrupt, IRQF_TRIGGER_NONE,
+ dev_name(&pdev->dev), pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "request_irq err\n");
+ return ret;
+ }
+ irq_set_irq_type(IRQ7, IRQ_TYPE_EDGE_BOTH);
+
/* usb24 use 1/1 of parent clock (= usb24s = 24MHz) */
clk_set_rate(priv->usb24,
clk_get_rate(clk_get_parent(priv->usb24)));
@@ -262,6 +297,7 @@ static struct usbhsf_private usbhsf_private = {
.info = {
.platform_callback = {
.get_id = usbhsf_get_id,
+ .get_vbus = usbhsf_get_vbus,
.hardware_init = usbhsf_hardware_init,
.hardware_exit = usbhsf_hardware_exit,
.power_ctrl = usbhsf_power_ctrl,
@@ -269,6 +305,8 @@ static struct usbhsf_private usbhsf_private = {
.driver_param = {
.buswait_bwait = 5,
.detection_delay = 5,
+ .d0_rx_id = SHDMA_SLAVE_USBHS_RX,
+ .d1_tx_id = SHDMA_SLAVE_USBHS_TX,
},
}
};
@@ -384,6 +422,103 @@ static struct platform_device lcdc0_device = {
},
};
+/*
+ * LCDC1/HDMI
+ */
+static struct sh_mobile_hdmi_info hdmi_info = {
+ .flags = HDMI_OUTPUT_PUSH_PULL |
+ HDMI_OUTPUT_POLARITY_HI |
+ HDMI_32BIT_REG |
+ HDMI_HAS_HTOP1 |
+ HDMI_SND_SRC_SPDIF,
+};
+
+static struct resource hdmi_resources[] = {
+ [0] = {
+ .name = "HDMI",
+ .start = 0xe6be0000,
+ .end = 0xe6be03ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x1700),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .name = "HDMI emma3pf",
+ .start = 0xe6be4000,
+ .end = 0xe6be43ff,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device hdmi_device = {
+ .name = "sh-mobile-hdmi",
+ .num_resources = ARRAY_SIZE(hdmi_resources),
+ .resource = hdmi_resources,
+ .id = -1,
+ .dev = {
+ .platform_data = &hdmi_info,
+ },
+};
+
+static const struct fb_videomode lcdc1_mode = {
+ .name = "HDMI 720p",
+ .xres = 1280,
+ .yres = 720,
+ .pixclock = 13468,
+ .left_margin = 220,
+ .right_margin = 110,
+ .hsync_len = 40,
+ .upper_margin = 20,
+ .lower_margin = 5,
+ .vsync_len = 5,
+ .refresh = 60,
+ .sync = FB_SYNC_VERT_HIGH_ACT | FB_SYNC_HOR_HIGH_ACT,
+};
+
+static struct sh_mobile_lcdc_info hdmi_lcdc_info = {
+ .clock_source = LCDC_CLK_PERIPHERAL, /* HDMI clock */
+ .ch[0] = {
+ .chan = LCDC_CHAN_MAINLCD,
+ .fourcc = V4L2_PIX_FMT_RGB565,
+ .interface_type = RGB24,
+ .clock_divider = 1,
+ .flags = LCDC_FLAGS_DWPOL,
+ .lcd_modes = &lcdc1_mode,
+ .num_modes = 1,
+ .tx_dev = &hdmi_device,
+ .panel_cfg = {
+ .width = 1280,
+ .height = 720,
+ },
+ },
+};
+
+static struct resource hdmi_lcdc_resources[] = {
+ [0] = {
+ .name = "LCDC1",
+ .start = 0xfe944000,
+ .end = 0xfe948000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x1780),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device hdmi_lcdc_device = {
+ .name = "sh_mobile_lcdc_fb",
+ .num_resources = ARRAY_SIZE(hdmi_lcdc_resources),
+ .resource = hdmi_lcdc_resources,
+ .id = 1,
+ .dev = {
+ .platform_data = &hdmi_lcdc_info,
+ .coherent_dma_mask = ~0,
+ },
+};
+
/* GPIO KEY */
#define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 }
@@ -407,6 +542,17 @@ static struct platform_device gpio_keys_device = {
},
};
+/* Fixed 3.3V regulator to be used by SDHI0, SDHI1, MMCIF */
+static struct regulator_consumer_supply fixed3v3_power_consumers[] =
+{
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"),
+ REGULATOR_SUPPLY("vmmc", "sh_mmcif"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mmcif"),
+};
+
/* SDHI0 */
/*
* FIXME
@@ -418,6 +564,8 @@ static struct platform_device gpio_keys_device = {
*/
#define IRQ31 evt2irq(0x33E0)
static struct sh_mobile_sdhi_info sdhi0_info = {
+ .dma_slave_tx = SHDMA_SLAVE_SDHI0_TX,
+ .dma_slave_rx = SHDMA_SLAVE_SDHI0_RX,
.tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |\
MMC_CAP_NEEDS_POLL,
.tmio_ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
@@ -458,6 +606,8 @@ static struct platform_device sdhi0_device = {
/* SDHI1 */
static struct sh_mobile_sdhi_info sdhi1_info = {
+ .dma_slave_tx = SHDMA_SLAVE_SDHI1_TX,
+ .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX,
.tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ,
.tmio_ocr_mask = MMC_VDD_165_195 | MMC_VDD_32_33 | MMC_VDD_33_34,
.tmio_flags = TMIO_MMC_HAS_IDLE_WAIT,
@@ -532,12 +682,209 @@ static struct platform_device sh_mmcif_device = {
.resource = sh_mmcif_resources,
};
+/* Camera */
+static int mt9t111_power(struct device *dev, int mode)
+{
+ struct clk *mclk = clk_get(NULL, "video1");
+
+ if (IS_ERR(mclk)) {
+ dev_err(dev, "can't get video1 clock\n");
+ return -EINVAL;
+ }
+
+ if (mode) {
+ /* video1 (= CON1 camera) expect 24MHz */
+ clk_set_rate(mclk, clk_round_rate(mclk, 24000000));
+ clk_enable(mclk);
+ gpio_direction_output(GPIO_PORT158, 1);
+ } else {
+ gpio_direction_output(GPIO_PORT158, 0);
+ clk_disable(mclk);
+ }
+
+ clk_put(mclk);
+
+ return 0;
+}
+
+static struct i2c_board_info i2c_camera_mt9t111 = {
+ I2C_BOARD_INFO("mt9t112", 0x3d),
+};
+
+static struct mt9t112_camera_info mt9t111_info = {
+ .divider = { 16, 0, 0, 7, 0, 10, 14, 7, 7 },
+};
+
+static struct soc_camera_link mt9t111_link = {
+ .i2c_adapter_id = 0,
+ .bus_id = 0,
+ .board_info = &i2c_camera_mt9t111,
+ .power = mt9t111_power,
+ .priv = &mt9t111_info,
+};
+
+static struct platform_device camera_device = {
+ .name = "soc-camera-pdrv",
+ .id = 0,
+ .dev = {
+ .platform_data = &mt9t111_link,
+ },
+};
+
+/* CEU0 */
+static struct sh_mobile_ceu_info sh_mobile_ceu0_info = {
+ .flags = SH_CEU_FLAG_LOWER_8BIT,
+};
+
+static struct resource ceu0_resources[] = {
+ [0] = {
+ .name = "CEU",
+ .start = 0xfe910000,
+ .end = 0xfe91009f,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = intcs_evt2irq(0x0500),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ /* place holder for contiguous memory */
+ },
+};
+
+static struct platform_device ceu0_device = {
+ .name = "sh_mobile_ceu",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(ceu0_resources),
+ .resource = ceu0_resources,
+ .dev = {
+ .platform_data = &sh_mobile_ceu0_info,
+ .coherent_dma_mask = 0xffffffff,
+ },
+};
+
+/* FSI */
+static int fsi_hdmi_set_rate(struct device *dev, int rate, int enable)
+{
+ struct clk *fsib;
+ int ret;
+
+ /* it support 48KHz only */
+ if (48000 != rate)
+ return -EINVAL;
+
+ fsib = clk_get(dev, "ickb");
+ if (IS_ERR(fsib))
+ return -EINVAL;
+
+ if (enable) {
+ ret = SH_FSI_ACKMD_256 | SH_FSI_BPFMD_64;
+ clk_enable(fsib);
+ } else {
+ ret = 0;
+ clk_disable(fsib);
+ }
+
+ clk_put(fsib);
+
+ return ret;
+}
+
+static struct sh_fsi_platform_info fsi_info = {
+ /* FSI-WM8978 */
+ .port_a = {
+ .tx_id = SHDMA_SLAVE_FSIA_TX,
+ },
+ /* FSI-HDMI */
+ .port_b = {
+ .flags = SH_FSI_FMT_SPDIF |
+ SH_FSI_ENABLE_STREAM_MODE,
+ .set_rate = fsi_hdmi_set_rate,
+ .tx_id = SHDMA_SLAVE_FSIB_TX,
+ }
+};
+
+static struct resource fsi_resources[] = {
+ [0] = {
+ .name = "FSI",
+ .start = 0xfe1f0000,
+ .end = 0xfe1f8400 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = evt2irq(0x1840),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device fsi_device = {
+ .name = "sh_fsi2",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(fsi_resources),
+ .resource = fsi_resources,
+ .dev = {
+ .platform_data = &fsi_info,
+ },
+};
+
+/* FSI-WM8978 */
+static struct asoc_simple_dai_init_info fsi_wm8978_init_info = {
+ .fmt = SND_SOC_DAIFMT_I2S,
+ .codec_daifmt = SND_SOC_DAIFMT_CBM_CFM | SND_SOC_DAIFMT_NB_NF,
+ .cpu_daifmt = SND_SOC_DAIFMT_CBS_CFS,
+ .sysclk = 12288000,
+};
+
+static struct asoc_simple_card_info fsi_wm8978_info = {
+ .name = "wm8978",
+ .card = "FSI2A-WM8978",
+ .cpu_dai = "fsia-dai",
+ .codec = "wm8978.0-001a",
+ .platform = "sh_fsi2",
+ .codec_dai = "wm8978-hifi",
+ .init = &fsi_wm8978_init_info,
+};
+
+static struct platform_device fsi_wm8978_device = {
+ .name = "asoc-simple-card",
+ .id = 0,
+ .dev = {
+ .platform_data = &fsi_wm8978_info,
+ },
+};
+
+/* FSI-HDMI */
+static struct asoc_simple_dai_init_info fsi2_hdmi_init_info = {
+ .cpu_daifmt = SND_SOC_DAIFMT_CBM_CFM,
+};
+
+static struct asoc_simple_card_info fsi2_hdmi_info = {
+ .name = "HDMI",
+ .card = "FSI2B-HDMI",
+ .cpu_dai = "fsib-dai",
+ .codec = "sh-mobile-hdmi",
+ .platform = "sh_fsi2",
+ .codec_dai = "sh_mobile_hdmi-hifi",
+ .init = &fsi2_hdmi_init_info,
+};
+
+static struct platform_device fsi_hdmi_device = {
+ .name = "asoc-simple-card",
+ .id = 1,
+ .dev = {
+ .platform_data = &fsi2_hdmi_info,
+ },
+};
+
/* I2C */
static struct i2c_board_info i2c0_devices[] = {
{
I2C_BOARD_INFO("st1232-ts", 0x55),
.irq = evt2irq(0x0340),
},
+ {
+ I2C_BOARD_INFO("wm8978", 0x1a),
+ },
};
/*
@@ -549,6 +896,13 @@ static struct platform_device *eva_devices[] __initdata = {
&sh_eth_device,
&sdhi0_device,
&sh_mmcif_device,
+ &hdmi_device,
+ &hdmi_lcdc_device,
+ &camera_device,
+ &ceu0_device,
+ &fsi_device,
+ &fsi_hdmi_device,
+ &fsi_wm8978_device,
};
static void __init eva_clock_init(void)
@@ -556,10 +910,14 @@ static void __init eva_clock_init(void)
struct clk *system = clk_get(NULL, "system_clk");
struct clk *xtal1 = clk_get(NULL, "extal1");
struct clk *usb24s = clk_get(NULL, "usb24s");
+ struct clk *fsibck = clk_get(NULL, "fsibck");
+ struct clk *fsib = clk_get(&fsi_device.dev, "ickb");
if (IS_ERR(system) ||
IS_ERR(xtal1) ||
- IS_ERR(usb24s)) {
+ IS_ERR(usb24s) ||
+ IS_ERR(fsibck) ||
+ IS_ERR(fsib)) {
pr_err("armadillo800eva board clock init failed\n");
goto clock_error;
}
@@ -570,6 +928,11 @@ static void __init eva_clock_init(void)
/* usb24s use extal1 (= system) clock (= 24MHz) */
clk_set_parent(usb24s, system);
+ /* FSIBCK is 12.288MHz, and it is parent of FSI-B */
+ clk_set_parent(fsib, fsibck);
+ clk_set_rate(fsibck, 12288000);
+ clk_set_rate(fsib, 12288000);
+
clock_error:
if (!IS_ERR(system))
clk_put(system);
@@ -577,16 +940,26 @@ clock_error:
clk_put(xtal1);
if (!IS_ERR(usb24s))
clk_put(usb24s);
+ if (!IS_ERR(fsibck))
+ clk_put(fsibck);
+ if (!IS_ERR(fsib))
+ clk_put(fsib);
}
/*
* board init
*/
+#define GPIO_PORT7CR 0xe6050007
+#define GPIO_PORT8CR 0xe6050008
static void __init eva_init(void)
{
- eva_clock_init();
+ struct platform_device *usb = NULL;
+
+ regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
+ ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
r8a7740_pinmux_init();
+ r8a7740_meram_workaround();
/* SCIFA1 */
gpio_request(GPIO_FN_SCIFA1_RXD, NULL);
@@ -667,8 +1040,19 @@ static void __init eva_init(void)
/* USB Host */
} else {
/* USB Func */
- gpio_request(GPIO_FN_VBUS, NULL);
+ /*
+ * A1 chip has 2 IRQ7 pin and it was controled by MSEL register.
+ * OTOH, usbhs interrupt needs its value (HI/LOW) to decide
+ * USB connection/disconnection (usbhsf_get_vbus()).
+ * This means we needs to select GPIO_FN_IRQ7_PORT209 first,
+ * and select GPIO_PORT209 here
+ */
+ gpio_request(GPIO_FN_IRQ7_PORT209, NULL);
+ gpio_request(GPIO_PORT209, NULL);
+ gpio_direction_input(GPIO_PORT209);
+
platform_device_register(&usbhsf_device);
+ usb = &usbhsf_device;
}
/* SDHI0 */
@@ -706,6 +1090,48 @@ static void __init eva_init(void)
gpio_request(GPIO_FN_MMC1_D6_PORT143, NULL);
gpio_request(GPIO_FN_MMC1_D7_PORT142, NULL);
+ /* CEU0 */
+ gpio_request(GPIO_FN_VIO0_D7, NULL);
+ gpio_request(GPIO_FN_VIO0_D6, NULL);
+ gpio_request(GPIO_FN_VIO0_D5, NULL);
+ gpio_request(GPIO_FN_VIO0_D4, NULL);
+ gpio_request(GPIO_FN_VIO0_D3, NULL);
+ gpio_request(GPIO_FN_VIO0_D2, NULL);
+ gpio_request(GPIO_FN_VIO0_D1, NULL);
+ gpio_request(GPIO_FN_VIO0_D0, NULL);
+ gpio_request(GPIO_FN_VIO0_CLK, NULL);
+ gpio_request(GPIO_FN_VIO0_HD, NULL);
+ gpio_request(GPIO_FN_VIO0_VD, NULL);
+ gpio_request(GPIO_FN_VIO0_FIELD, NULL);
+ gpio_request(GPIO_FN_VIO_CKO, NULL);
+
+ /* CON1/CON15 Camera */
+ gpio_request(GPIO_PORT173, NULL); /* STANDBY */
+ gpio_request(GPIO_PORT172, NULL); /* RST */
+ gpio_request(GPIO_PORT158, NULL); /* CAM_PON */
+ gpio_direction_output(GPIO_PORT173, 0);
+ gpio_direction_output(GPIO_PORT172, 1);
+ gpio_direction_output(GPIO_PORT158, 0); /* see mt9t111_power() */
+
+ /* FSI-WM8978 */
+ gpio_request(GPIO_FN_FSIAIBT, NULL);
+ gpio_request(GPIO_FN_FSIAILR, NULL);
+ gpio_request(GPIO_FN_FSIAOMC, NULL);
+ gpio_request(GPIO_FN_FSIAOSLD, NULL);
+ gpio_request(GPIO_FN_FSIAISLD_PORT5, NULL);
+
+ gpio_request(GPIO_PORT7, NULL);
+ gpio_request(GPIO_PORT8, NULL);
+ gpio_direction_none(GPIO_PORT7CR); /* FSIAOBT needs no direction */
+ gpio_direction_none(GPIO_PORT8CR); /* FSIAOLR needs no direction */
+
+ /* FSI-HDMI */
+ gpio_request(GPIO_FN_FSIBCK, NULL);
+
+ /* HDMI */
+ gpio_request(GPIO_FN_HDMI_HPD, NULL);
+ gpio_request(GPIO_FN_HDMI_CEC, NULL);
+
/*
* CAUTION
*
@@ -752,6 +1178,13 @@ static void __init eva_init(void)
platform_add_devices(eva_devices,
ARRAY_SIZE(eva_devices));
+
+ eva_clock_init();
+
+ rmobile_add_device_to_domain(&r8a7740_pd_a4lc, &lcdc0_device);
+ rmobile_add_device_to_domain(&r8a7740_pd_a4lc, &hdmi_lcdc_device);
+ if (usb)
+ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, usb);
}
static void __init eva_earlytimer_init(void)
diff --git a/arch/arm/mach-shmobile/board-bonito.c b/arch/arm/mach-shmobile/board-bonito.c
index e9b32cfbf74..4129008eae2 100644
--- a/arch/arm/mach-shmobile/board-bonito.c
+++ b/arch/arm/mach-shmobile/board-bonito.c
@@ -26,6 +26,8 @@
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/gpio.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
#include <linux/smsc911x.h>
#include <linux/videodev2.h>
#include <mach/common.h>
@@ -75,6 +77,12 @@
* S38.2 = OFF
*/
+/* Dummy supplies, where voltage doesn't matter */
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+};
+
/*
* FPGA
*/
@@ -360,6 +368,8 @@ static void __init bonito_init(void)
{
u16 val;
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
r8a7740_pinmux_init();
bonito_fpga_init();
diff --git a/arch/arm/mach-shmobile/board-g4evm.c b/arch/arm/mach-shmobile/board-g4evm.c
index f1257321999..fa5dfc5c8ed 100644
--- a/arch/arm/mach-shmobile/board-g4evm.c
+++ b/arch/arm/mach-shmobile/board-g4evm.c
@@ -26,6 +26,8 @@
#include <linux/mtd/mtd.h>
#include <linux/mtd/partitions.h>
#include <linux/mtd/physmap.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
#include <linux/usb/r8a66597.h>
#include <linux/io.h>
#include <linux/input.h>
@@ -196,6 +198,15 @@ static struct platform_device keysc_device = {
},
};
+/* Fixed 3.3V regulator to be used by SDHI0 and SDHI1 */
+static struct regulator_consumer_supply fixed3v3_power_consumers[] =
+{
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"),
+};
+
/* SDHI */
static struct sh_mobile_sdhi_info sdhi0_info = {
.tmio_caps = MMC_CAP_SDIO_IRQ,
@@ -271,26 +282,11 @@ static struct platform_device *g4evm_devices[] __initdata = {
#define GPIO_SDHID1_D3 0xe6052106
#define GPIO_SDHICMD1 0xe6052107
-/*
- * FIXME !!
- *
- * gpio_pull_up is quick_hack.
- *
- * current gpio frame work doesn't have
- * the method to control only pull up/down/free.
- * this function should be replaced by correct gpio function
- */
-static void __init gpio_pull_up(u32 addr)
-{
- u8 data = __raw_readb(addr);
-
- data &= 0x0F;
- data |= 0xC0;
- __raw_writeb(data, addr);
-}
-
static void __init g4evm_init(void)
{
+ regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers,
+ ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
+
sh7377_pinmux_init();
/* Lit DS14 LED */
@@ -351,11 +347,11 @@ static void __init g4evm_init(void)
gpio_request(GPIO_FN_SDHID0_3, NULL);
gpio_request(GPIO_FN_SDHICMD0, NULL);
gpio_request(GPIO_FN_SDHIWP0, NULL);
- gpio_pull_up(GPIO_SDHID0_D0);
- gpio_pull_up(GPIO_SDHID0_D1);
- gpio_pull_up(GPIO_SDHID0_D2);
- gpio_pull_up(GPIO_SDHID0_D3);
- gpio_pull_up(GPIO_SDHICMD0);
+ gpio_request_pullup(GPIO_SDHID0_D0);
+ gpio_request_pullup(GPIO_SDHID0_D1);
+ gpio_request_pullup(GPIO_SDHID0_D2);
+ gpio_request_pullup(GPIO_SDHID0_D3);
+ gpio_request_pullup(GPIO_SDHICMD0);
/* SDHI1 */
gpio_request(GPIO_FN_SDHICLK1, NULL);
@@ -364,11 +360,11 @@ static void __init g4evm_init(void)
gpio_request(GPIO_FN_SDHID1_2, NULL);
gpio_request(GPIO_FN_SDHID1_3, NULL);
gpio_request(GPIO_FN_SDHICMD1, NULL);
- gpio_pull_up(GPIO_SDHID1_D0);
- gpio_pull_up(GPIO_SDHID1_D1);
- gpio_pull_up(GPIO_SDHID1_D2);
- gpio_pull_up(GPIO_SDHID1_D3);
- gpio_pull_up(GPIO_SDHICMD1);
+ gpio_request_pullup(GPIO_SDHID1_D0);
+ gpio_request_pullup(GPIO_SDHID1_D1);
+ gpio_request_pullup(GPIO_SDHID1_D2);
+ gpio_request_pullup(GPIO_SDHID1_D3);
+ gpio_request_pullup(GPIO_SDHICMD1);
sh7377_add_standard_devices();
diff --git a/arch/arm/mach-shmobile/board-kota2.c b/arch/arm/mach-shmobile/board-kota2.c
index f60f1b281cc..21dbe54304d 100644
--- a/arch/arm/mach-shmobile/board-kota2.c
+++ b/arch/arm/mach-shmobile/board-kota2.c
@@ -27,6 +27,8 @@
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/io.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
#include <linux/smsc911x.h>
#include <linux/gpio.h>
#include <linux/input.h>
@@ -49,6 +51,12 @@
#include <asm/hardware/cache-l2x0.h>
#include <asm/traps.h>
+/* Dummy supplies, where voltage doesn't matter */
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+};
+
/* SMSC 9220 */
static struct resource smsc9220_resources[] = {
[0] = {
@@ -288,6 +296,13 @@ static struct platform_device leds_tpu30_device = {
.resource = tpu30_resources,
};
+/* Fixed 1.8V regulator to be used by MMCIF */
+static struct regulator_consumer_supply fixed1v8_power_consumers[] =
+{
+ REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"),
+};
+
/* MMCIF */
static struct resource mmcif_resources[] = {
[0] = {
@@ -321,6 +336,15 @@ static struct platform_device mmcif_device = {
.resource = mmcif_resources,
};
+/* Fixed 3.3V regulator to be used by SDHI0 and SDHI1 */
+static struct regulator_consumer_supply fixed3v3_power_consumers[] =
+{
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"),
+};
+
/* SDHI0 */
static struct sh_mobile_sdhi_info sdhi0_info = {
.tmio_caps = MMC_CAP_SD_HIGHSPEED,
@@ -411,6 +435,12 @@ static struct platform_device *kota2_devices[] __initdata = {
static void __init kota2_init(void)
{
+ regulator_register_always_on(0, "fixed-1.8V", fixed1v8_power_consumers,
+ ARRAY_SIZE(fixed1v8_power_consumers), 1800000);
+ regulator_register_always_on(1, "fixed-3.3V", fixed3v3_power_consumers,
+ ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
+ regulator_register_fixed(2, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
sh73a0_pinmux_init();
/* SCIFA2 (UART2) */
diff --git a/arch/arm/mach-shmobile/board-kzm9d.c b/arch/arm/mach-shmobile/board-kzm9d.c
index 6a33cf39342..2c986eaae7b 100644
--- a/arch/arm/mach-shmobile/board-kzm9d.c
+++ b/arch/arm/mach-shmobile/board-kzm9d.c
@@ -21,6 +21,8 @@
#include <linux/kernel.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
#include <linux/smsc911x.h>
#include <mach/common.h>
#include <mach/emev2.h>
@@ -28,6 +30,12 @@
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
+/* Dummy supplies, where voltage doesn't matter */
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+};
+
/* Ether */
static struct resource smsc911x_resources[] = {
[0] = {
@@ -63,6 +71,8 @@ static struct platform_device *kzm9d_devices[] __initdata = {
void __init kzm9d_add_standard_devices(void)
{
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
emev2_add_standard_devices();
platform_add_devices(kzm9d_devices, ARRAY_SIZE(kzm9d_devices));
diff --git a/arch/arm/mach-shmobile/board-kzm9g.c b/arch/arm/mach-shmobile/board-kzm9g.c
index c0ae815e7be..53b7ea92c32 100644
--- a/arch/arm/mach-shmobile/board-kzm9g.c
+++ b/arch/arm/mach-shmobile/board-kzm9g.c
@@ -30,9 +30,14 @@
#include <linux/mmc/sh_mobile_sdhi.h>
#include <linux/mfd/tmio.h>
#include <linux/platform_device.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
#include <linux/smsc911x.h>
#include <linux/usb/r8a66597.h>
+#include <linux/usb/renesas_usbhs.h>
#include <linux/videodev2.h>
+#include <sound/sh_fsi.h>
+#include <sound/simple_card.h>
#include <mach/irqs.h>
#include <mach/sh73a0.h>
#include <mach/common.h>
@@ -54,6 +59,20 @@
#define GPIO_PCF8575_PORT15 (GPIO_NR + 13)
#define GPIO_PCF8575_PORT16 (GPIO_NR + 14)
+/* Dummy supplies, where voltage doesn't matter */
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+};
+
+/*
+ * FSI-AK4648
+ *
+ * this command is required when playback.
+ *
+ * # amixer set "LINEOUT Mixer DACL" on
+ */
+
/* SMSC 9221 */
static struct resource smsc9221_resources[] = {
[0] = {
@@ -112,6 +131,151 @@ static struct platform_device usb_host_device = {
.resource = usb_resources,
};
+/* USB Func CN17 */
+struct usbhs_private {
+ unsigned int phy;
+ unsigned int cr2;
+ struct renesas_usbhs_platform_info info;
+};
+
+#define IRQ15 intcs_evt2irq(0x03e0)
+#define USB_PHY_MODE (1 << 4)
+#define USB_PHY_INT_EN ((1 << 3) | (1 << 2))
+#define USB_PHY_ON (1 << 1)
+#define USB_PHY_OFF (1 << 0)
+#define USB_PHY_INT_CLR (USB_PHY_ON | USB_PHY_OFF)
+
+#define usbhs_get_priv(pdev) \
+ container_of(renesas_usbhs_get_info(pdev), struct usbhs_private, info)
+
+static int usbhs_get_vbus(struct platform_device *pdev)
+{
+ struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+ return !((1 << 7) & __raw_readw(priv->cr2));
+}
+
+static void usbhs_phy_reset(struct platform_device *pdev)
+{
+ struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+ /* init phy */
+ __raw_writew(0x8a0a, priv->cr2);
+}
+
+static int usbhs_get_id(struct platform_device *pdev)
+{
+ return USBHS_GADGET;
+}
+
+static irqreturn_t usbhs_interrupt(int irq, void *data)
+{
+ struct platform_device *pdev = data;
+ struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+ renesas_usbhs_call_notify_hotplug(pdev);
+
+ /* clear status */
+ __raw_writew(__raw_readw(priv->phy) | USB_PHY_INT_CLR, priv->phy);
+
+ return IRQ_HANDLED;
+}
+
+static int usbhs_hardware_init(struct platform_device *pdev)
+{
+ struct usbhs_private *priv = usbhs_get_priv(pdev);
+ int ret;
+
+ /* clear interrupt status */
+ __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->phy);
+
+ ret = request_irq(IRQ15, usbhs_interrupt, IRQF_TRIGGER_HIGH,
+ dev_name(&pdev->dev), pdev);
+ if (ret) {
+ dev_err(&pdev->dev, "request_irq err\n");
+ return ret;
+ }
+
+ /* enable USB phy interrupt */
+ __raw_writew(USB_PHY_MODE | USB_PHY_INT_EN, priv->phy);
+
+ return 0;
+}
+
+static void usbhs_hardware_exit(struct platform_device *pdev)
+{
+ struct usbhs_private *priv = usbhs_get_priv(pdev);
+
+ /* clear interrupt status */
+ __raw_writew(USB_PHY_MODE | USB_PHY_INT_CLR, priv->phy);
+
+ free_irq(IRQ15, pdev);
+}
+
+static u32 usbhs_pipe_cfg[] = {
+ USB_ENDPOINT_XFER_CONTROL,
+ USB_ENDPOINT_XFER_ISOC,
+ USB_ENDPOINT_XFER_ISOC,
+ USB_ENDPOINT_XFER_BULK,
+ USB_ENDPOINT_XFER_BULK,
+ USB_ENDPOINT_XFER_BULK,
+ USB_ENDPOINT_XFER_INT,
+ USB_ENDPOINT_XFER_INT,
+ USB_ENDPOINT_XFER_INT,
+ USB_ENDPOINT_XFER_BULK,
+ USB_ENDPOINT_XFER_BULK,
+ USB_ENDPOINT_XFER_BULK,
+ USB_ENDPOINT_XFER_BULK,
+ USB_ENDPOINT_XFER_BULK,
+ USB_ENDPOINT_XFER_BULK,
+ USB_ENDPOINT_XFER_BULK,
+};
+
+static struct usbhs_private usbhs_private = {
+ .phy = 0xe60781e0, /* USBPHYINT */
+ .cr2 = 0xe605810c, /* USBCR2 */
+ .info = {
+ .platform_callback = {
+ .hardware_init = usbhs_hardware_init,
+ .hardware_exit = usbhs_hardware_exit,
+ .get_id = usbhs_get_id,
+ .phy_reset = usbhs_phy_reset,
+ .get_vbus = usbhs_get_vbus,
+ },
+ .driver_param = {
+ .buswait_bwait = 4,
+ .has_otg = 1,
+ .pipe_type = usbhs_pipe_cfg,
+ .pipe_size = ARRAY_SIZE(usbhs_pipe_cfg),
+ },
+ },
+};
+
+static struct resource usbhs_resources[] = {
+ [0] = {
+ .start = 0xE6890000,
+ .end = 0xE68900e6 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(62),
+ .end = gic_spi(62),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usbhs_device = {
+ .name = "renesas_usbhs",
+ .id = -1,
+ .dev = {
+ .dma_mask = NULL,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &usbhs_private.info,
+ },
+ .num_resources = ARRAY_SIZE(usbhs_resources),
+ .resource = usbhs_resources,
+};
+
/* LCDC */
static struct fb_videomode kzm_lcdc_mode = {
.name = "WVGA Panel",
@@ -166,6 +330,13 @@ static struct platform_device lcdc_device = {
},
};
+/* Fixed 1.8V regulator to be used by MMCIF */
+static struct regulator_consumer_supply fixed1v8_power_consumers[] =
+{
+ REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"),
+};
+
/* MMCIF */
static struct resource sh_mmcif_resources[] = {
[0] = {
@@ -187,6 +358,8 @@ static struct resource sh_mmcif_resources[] = {
static struct sh_mmcif_plat_data sh_mmcif_platdata = {
.ocr = MMC_VDD_165_195,
.caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
+ .slave_id_tx = SHDMA_SLAVE_MMCIF_TX,
+ .slave_id_rx = SHDMA_SLAVE_MMCIF_RX,
};
static struct platform_device mmc_device = {
@@ -200,6 +373,15 @@ static struct platform_device mmc_device = {
.resource = sh_mmcif_resources,
};
+/* Fixed 2.8V regulators to be used by SDHI0 and SDHI2 */
+static struct regulator_consumer_supply fixed2v8_power_consumers[] =
+{
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.2"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.2"),
+};
+
/* SDHI */
static struct sh_mobile_sdhi_info sdhi0_info = {
.tmio_flags = TMIO_MMC_HAS_IDLE_WAIT,
@@ -240,6 +422,50 @@ static struct platform_device sdhi0_device = {
},
};
+/* Micro SD */
+static struct sh_mobile_sdhi_info sdhi2_info = {
+ .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT |
+ TMIO_MMC_USE_GPIO_CD |
+ TMIO_MMC_WRPROTECT_DISABLE,
+ .tmio_caps = MMC_CAP_SD_HIGHSPEED,
+ .tmio_ocr_mask = MMC_VDD_27_28 | MMC_VDD_28_29,
+ .cd_gpio = GPIO_PORT13,
+};
+
+static struct resource sdhi2_resources[] = {
+ [0] = {
+ .name = "SDHI2",
+ .start = 0xee140000,
+ .end = 0xee1400ff,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = SH_MOBILE_SDHI_IRQ_CARD_DETECT,
+ .start = gic_spi(103),
+ .flags = IORESOURCE_IRQ,
+ },
+ [2] = {
+ .name = SH_MOBILE_SDHI_IRQ_SDCARD,
+ .start = gic_spi(104),
+ .flags = IORESOURCE_IRQ,
+ },
+ [3] = {
+ .name = SH_MOBILE_SDHI_IRQ_SDIO,
+ .start = gic_spi(105),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device sdhi2_device = {
+ .name = "sh_mobile_sdhi",
+ .id = 2,
+ .num_resources = ARRAY_SIZE(sdhi2_resources),
+ .resource = sdhi2_resources,
+ .dev = {
+ .platform_data = &sdhi2_info,
+ },
+};
+
/* KEY */
#define GPIO_KEY(c, g, d) { .code = c, .gpio = g, .desc = d, .active_low = 1 }
@@ -267,11 +493,74 @@ static struct platform_device gpio_keys_device = {
},
};
+/* FSI-AK4648 */
+static struct sh_fsi_platform_info fsi_info = {
+ .port_a = {
+ .tx_id = SHDMA_SLAVE_FSI2A_TX,
+ },
+};
+
+static struct resource fsi_resources[] = {
+ [0] = {
+ .name = "FSI",
+ .start = 0xEC230000,
+ .end = 0xEC230400 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = gic_spi(146),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device fsi_device = {
+ .name = "sh_fsi2",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(fsi_resources),
+ .resource = fsi_resources,
+ .dev = {
+ .platform_data = &fsi_info,
+ },
+};
+
+static struct asoc_simple_dai_init_info fsi2_ak4648_init_info = {
+ .fmt = SND_SOC_DAIFMT_LEFT_J,
+ .codec_daifmt = SND_SOC_DAIFMT_CBM_CFM,
+ .cpu_daifmt = SND_SOC_DAIFMT_CBS_CFS,
+ .sysclk = 11289600,
+};
+
+static struct asoc_simple_card_info fsi2_ak4648_info = {
+ .name = "AK4648",
+ .card = "FSI2A-AK4648",
+ .cpu_dai = "fsia-dai",
+ .codec = "ak4642-codec.0-0012",
+ .platform = "sh_fsi2",
+ .codec_dai = "ak4642-hifi",
+ .init = &fsi2_ak4648_init_info,
+};
+
+static struct platform_device fsi_ak4648_device = {
+ .name = "asoc-simple-card",
+ .dev = {
+ .platform_data = &fsi2_ak4648_info,
+ },
+};
+
/* I2C */
static struct pcf857x_platform_data pcf8575_pdata = {
.gpio_base = GPIO_PCF8575_BASE,
};
+static struct i2c_board_info i2c0_devices[] = {
+ {
+ I2C_BOARD_INFO("ak4648", 0x12),
+ },
+ {
+ I2C_BOARD_INFO("r2025sd", 0x32),
+ }
+};
+
static struct i2c_board_info i2c1_devices[] = {
{
I2C_BOARD_INFO("st1232-ts", 0x55),
@@ -289,10 +578,14 @@ static struct i2c_board_info i2c3_devices[] = {
static struct platform_device *kzm_devices[] __initdata = {
&smsc_device,
&usb_host_device,
+ &usbhs_device,
&lcdc_device,
&mmc_device,
&sdhi0_device,
+ &sdhi2_device,
&gpio_keys_device,
+ &fsi_device,
+ &fsi_ak4648_device,
};
/*
@@ -350,6 +643,12 @@ device_initcall(as3711_enable_lcdc_backlight);
static void __init kzm_init(void)
{
+ regulator_register_always_on(0, "fixed-1.8V", fixed1v8_power_consumers,
+ ARRAY_SIZE(fixed1v8_power_consumers), 1800000);
+ regulator_register_always_on(1, "fixed-2.8V", fixed2v8_power_consumers,
+ ARRAY_SIZE(fixed2v8_power_consumers), 2800000);
+ regulator_register_fixed(2, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
sh73a0_pinmux_init();
/* enable SCIFA4 */
@@ -427,15 +726,36 @@ static void __init kzm_init(void)
gpio_request(GPIO_PORT15, NULL);
gpio_direction_output(GPIO_PORT15, 1); /* power */
+ /* enable Micro SD */
+ gpio_request(GPIO_FN_SDHID2_0, NULL);
+ gpio_request(GPIO_FN_SDHID2_1, NULL);
+ gpio_request(GPIO_FN_SDHID2_2, NULL);
+ gpio_request(GPIO_FN_SDHID2_3, NULL);
+ gpio_request(GPIO_FN_SDHICMD2, NULL);
+ gpio_request(GPIO_FN_SDHICLK2, NULL);
+ gpio_request(GPIO_PORT14, NULL);
+ gpio_direction_output(GPIO_PORT14, 1); /* power */
+
/* I2C 3 */
gpio_request(GPIO_FN_PORT27_I2C_SCL3, NULL);
gpio_request(GPIO_FN_PORT28_I2C_SDA3, NULL);
+ /* enable FSI2 port A (ak4648) */
+ gpio_request(GPIO_FN_FSIACK, NULL);
+ gpio_request(GPIO_FN_FSIAILR, NULL);
+ gpio_request(GPIO_FN_FSIAIBT, NULL);
+ gpio_request(GPIO_FN_FSIAISLD, NULL);
+ gpio_request(GPIO_FN_FSIAOSLD, NULL);
+
+ /* enable USB */
+ gpio_request(GPIO_FN_VBUS_0, NULL);
+
#ifdef CONFIG_CACHE_L2X0
/* Early BRESP enable, Shared attribute override enable, 64K*8way */
l2x0_init(IOMEM(0xf0100000), 0x40460000, 0x82000fff);
#endif
+ i2c_register_board_info(0, i2c0_devices, ARRAY_SIZE(i2c0_devices));
i2c_register_board_info(1, i2c1_devices, ARRAY_SIZE(i2c1_devices));
i2c_register_board_info(3, i2c3_devices, ARRAY_SIZE(i2c3_devices));
diff --git a/arch/arm/mach-shmobile/board-mackerel.c b/arch/arm/mach-shmobile/board-mackerel.c
index 150122a4463..7ea2b31e319 100644
--- a/arch/arm/mach-shmobile/board-mackerel.c
+++ b/arch/arm/mach-shmobile/board-mackerel.c
@@ -41,6 +41,8 @@
#include <linux/mtd/physmap.h>
#include <linux/mtd/sh_flctl.h>
#include <linux/pm_clock.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
#include <linux/smsc911x.h>
#include <linux/sh_intc.h>
#include <linux/tca6416_keypad.h>
@@ -203,31 +205,32 @@
* amixer set "HPOUTR Mixer DACH" on
*/
-/*
- * FIXME !!
- *
- * gpio_no_direction
- * gpio_pull_down
- * are quick_hack.
- *
- * current gpio frame work doesn't have
- * the method to control only pull up/down/free.
- * this function should be replaced by correct gpio function
- */
-static void __init gpio_no_direction(u32 addr)
+/* Fixed 3.3V and 1.8V regulators to be used by multiple devices */
+static struct regulator_consumer_supply fixed1v8_power_consumers[] =
{
- __raw_writeb(0x00, addr);
-}
+ /*
+ * J22 on mackerel switches mmcif.0 and sdhi.1 between 1.8V and 3.3V
+ * Since we cannot support both voltages, we support the default 1.8V
+ */
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"),
+ REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"),
+};
-static void __init gpio_pull_down(u32 addr)
+static struct regulator_consumer_supply fixed3v3_power_consumers[] =
{
- u8 data = __raw_readb(addr);
-
- data &= 0x0F;
- data |= 0xA0;
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"),
+ REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.2"),
+ REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.2"),
+};
- __raw_writeb(data, addr);
-}
+/* Dummy supplies, where voltage doesn't matter */
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+};
/* MTD */
static struct mtd_partition nor_flash_partitions[] = {
@@ -1409,6 +1412,12 @@ static void __init mackerel_init(void)
u32 srcr4;
struct clk *clk;
+ regulator_register_always_on(0, "fixed-1.8V", fixed1v8_power_consumers,
+ ARRAY_SIZE(fixed1v8_power_consumers), 1800000);
+ regulator_register_always_on(1, "fixed-3.3V", fixed3v3_power_consumers,
+ ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
+ regulator_register_fixed(2, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
/* External clock source */
clk_set_rate(&sh7372_dv_clki_clk, 27000000);
@@ -1458,11 +1467,11 @@ static void __init mackerel_init(void)
/* USBHS0 */
gpio_request(GPIO_FN_VBUS0_0, NULL);
- gpio_pull_down(GPIO_PORT168CR); /* VBUS0_0 pull down */
+ gpio_request_pulldown(GPIO_PORT168CR); /* VBUS0_0 pull down */
/* USBHS1 */
gpio_request(GPIO_FN_VBUS0_1, NULL);
- gpio_pull_down(GPIO_PORT167CR); /* VBUS0_1 pull down */
+ gpio_request_pulldown(GPIO_PORT167CR); /* VBUS0_1 pull down */
gpio_request(GPIO_FN_IDIN_1_113, NULL);
/* enable FSI2 port A (ak4643) */
@@ -1475,8 +1484,8 @@ static void __init mackerel_init(void)
gpio_request(GPIO_PORT9, NULL);
gpio_request(GPIO_PORT10, NULL);
- gpio_no_direction(GPIO_PORT9CR); /* FSIAOBT needs no direction */
- gpio_no_direction(GPIO_PORT10CR); /* FSIAOLR needs no direction */
+ gpio_direction_none(GPIO_PORT9CR); /* FSIAOBT needs no direction */
+ gpio_direction_none(GPIO_PORT10CR); /* FSIAOLR needs no direction */
intc_set_priority(IRQ_FSI, 3); /* irq priority FSI(3) > SMSC911X(2) */
@@ -1614,20 +1623,20 @@ static void __init mackerel_init(void)
platform_add_devices(mackerel_devices, ARRAY_SIZE(mackerel_devices));
- sh7372_add_device_to_domain(&sh7372_a4lc, &lcdc_device);
- sh7372_add_device_to_domain(&sh7372_a4lc, &hdmi_lcdc_device);
- sh7372_add_device_to_domain(&sh7372_a4lc, &meram_device);
- sh7372_add_device_to_domain(&sh7372_a4mp, &fsi_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &usbhs0_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &usbhs1_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &nand_flash_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &sh_mmcif_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi0_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4lc, &lcdc_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4lc, &hdmi_lcdc_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4lc, &meram_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4mp, &fsi_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usbhs0_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usbhs1_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &nand_flash_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sh_mmcif_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi0_device);
#if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
- sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi1_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi1_device);
#endif
- sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi2_device);
- sh7372_add_device_to_domain(&sh7372_a4r, &ceu_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &sdhi2_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4r, &ceu_device);
hdmi_init_pm_clock();
sh7372_pm_init();
diff --git a/arch/arm/mach-shmobile/board-marzen.c b/arch/arm/mach-shmobile/board-marzen.c
index 14de3787caf..3a528cf4366 100644
--- a/arch/arm/mach-shmobile/board-marzen.c
+++ b/arch/arm/mach-shmobile/board-marzen.c
@@ -27,6 +27,8 @@
#include <linux/io.h>
#include <linux/gpio.h>
#include <linux/dma-mapping.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
#include <linux/smsc911x.h>
#include <mach/hardware.h>
#include <mach/r8a7779.h>
@@ -37,6 +39,12 @@
#include <asm/hardware/gic.h>
#include <asm/traps.h>
+/* Dummy supplies, where voltage doesn't matter */
+static struct regulator_consumer_supply dummy_supplies[] = {
+ REGULATOR_SUPPLY("vddvario", "smsc911x"),
+ REGULATOR_SUPPLY("vdd33a", "smsc911x"),
+};
+
/* SMSC LAN89218 */
static struct resource smsc911x_resources[] = {
[0] = {
@@ -73,6 +81,8 @@ static struct platform_device *marzen_devices[] __initdata = {
static void __init marzen_init(void)
{
+ regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies));
+
r8a7779_pinmux_init();
/* SCIF2 (CN18: DEBUG0) */
diff --git a/arch/arm/mach-shmobile/clock-r8a7740.c b/arch/arm/mach-shmobile/clock-r8a7740.c
index 26eea5f2105..ad5fccc7b5e 100644
--- a/arch/arm/mach-shmobile/clock-r8a7740.c
+++ b/arch/arm/mach-shmobile/clock-r8a7740.c
@@ -43,7 +43,10 @@
/* CPG registers */
#define FRQCRA 0xe6150000
#define FRQCRB 0xe6150004
+#define VCLKCR1 0xE6150008
+#define VCLKCR2 0xE615000c
#define FRQCRC 0xe61500e0
+#define FSIACKCR 0xe6150018
#define PLLC01CR 0xe6150028
#define SUBCKCR 0xe6150080
@@ -54,6 +57,8 @@
#define MSTPSR2 0xe6150040
#define MSTPSR3 0xe6150048
#define MSTPSR4 0xe615004c
+#define FSIBCKCR 0xe6150090
+#define HDMICKCR 0xe6150094
#define SMSTPCR0 0xe6150130
#define SMSTPCR1 0xe6150134
#define SMSTPCR2 0xe6150138
@@ -271,6 +276,13 @@ static struct clk usb24_clk = {
.parent = &usb24s_clk,
};
+/* External FSIACK/FSIBCK clock */
+static struct clk fsiack_clk = {
+};
+
+static struct clk fsibck_clk = {
+};
+
struct clk *main_clks[] = {
&extalr_clk,
&extal1_clk,
@@ -288,6 +300,8 @@ struct clk *main_clks[] = {
&pllc1_div2_clk,
&usb24s_clk,
&usb24_clk,
+ &fsiack_clk,
+ &fsibck_clk,
};
static void div4_kick(struct clk *clk)
@@ -313,6 +327,107 @@ static struct clk_div4_table div4_table = {
.kick = div4_kick,
};
+/* DIV6 reparent */
+enum {
+ DIV6_HDMI,
+ DIV6_VCLK1, DIV6_VCLK2,
+ DIV6_FSIA, DIV6_FSIB,
+ DIV6_REPARENT_NR,
+};
+
+static struct clk *hdmi_parent[] = {
+ [0] = &pllc1_div2_clk,
+ [1] = &system_clk,
+ [2] = &dv_clk
+};
+
+static struct clk *vclk_parents[8] = {
+ [0] = &pllc1_div2_clk,
+ [2] = &dv_clk,
+ [3] = &usb24s_clk,
+ [4] = &extal1_div2_clk,
+ [5] = &extalr_clk,
+};
+
+static struct clk *fsia_parents[] = {
+ [0] = &pllc1_div2_clk,
+ [1] = &fsiack_clk, /* external clock */
+};
+
+static struct clk *fsib_parents[] = {
+ [0] = &pllc1_div2_clk,
+ [1] = &fsibck_clk, /* external clock */
+};
+
+static struct clk div6_reparent_clks[DIV6_REPARENT_NR] = {
+ [DIV6_HDMI] = SH_CLK_DIV6_EXT(HDMICKCR, 0,
+ hdmi_parent, ARRAY_SIZE(hdmi_parent), 6, 2),
+ [DIV6_VCLK1] = SH_CLK_DIV6_EXT(VCLKCR1, 0,
+ vclk_parents, ARRAY_SIZE(vclk_parents), 12, 3),
+ [DIV6_VCLK2] = SH_CLK_DIV6_EXT(VCLKCR2, 0,
+ vclk_parents, ARRAY_SIZE(vclk_parents), 12, 3),
+ [DIV6_FSIA] = SH_CLK_DIV6_EXT(FSIACKCR, 0,
+ fsia_parents, ARRAY_SIZE(fsia_parents), 6, 2),
+ [DIV6_FSIB] = SH_CLK_DIV6_EXT(FSIBCKCR, 0,
+ fsib_parents, ARRAY_SIZE(fsib_parents), 6, 2),
+};
+
+/* HDMI1/2 clock */
+static unsigned long hdmi12_recalc(struct clk *clk)
+{
+ u32 val = __raw_readl(HDMICKCR);
+ int shift = (int)clk->priv;
+
+ val >>= shift;
+ val &= 0x3;
+
+ return clk->parent->rate / (1 << val);
+};
+
+static int hdmi12_set_rate(struct clk *clk, unsigned long rate)
+{
+ u32 val, mask;
+ int i, shift;
+
+ for (i = 0; i < 3; i++)
+ if (rate == clk->parent->rate / (1 << i))
+ goto find;
+ return -ENODEV;
+
+find:
+ shift = (int)clk->priv;
+
+ val = __raw_readl(HDMICKCR);
+ mask = ~(0x3 << shift);
+ val = (val & mask) | i << shift;
+ __raw_writel(val, HDMICKCR);
+
+ return 0;
+};
+
+static struct sh_clk_ops hdmi12_clk_ops = {
+ .recalc = hdmi12_recalc,
+ .set_rate = hdmi12_set_rate,
+};
+
+static struct clk hdmi1_clk = {
+ .ops = &hdmi12_clk_ops,
+ .priv = (void *)9,
+ .parent = &div6_reparent_clks[DIV6_HDMI], /* late install */
+};
+
+static struct clk hdmi2_clk = {
+ .ops = &hdmi12_clk_ops,
+ .priv = (void *)11,
+ .parent = &div6_reparent_clks[DIV6_HDMI], /* late install */
+};
+
+static struct clk *late_main_clks[] = {
+ &hdmi1_clk,
+ &hdmi2_clk,
+};
+
+/* MSTP */
enum {
DIV4_I, DIV4_ZG, DIV4_B, DIV4_M1, DIV4_HP,
DIV4_HPP, DIV4_USBP, DIV4_S, DIV4_ZB, DIV4_M3, DIV4_CP,
@@ -343,11 +458,12 @@ static struct clk div6_clks[DIV6_NR] = {
};
enum {
- MSTP125,
+ MSTP128, MSTP127, MSTP125,
MSTP116, MSTP111, MSTP100, MSTP117,
MSTP230,
MSTP222,
+ MSTP218, MSTP217, MSTP216, MSTP214,
MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
MSTP329, MSTP328, MSTP323, MSTP320,
@@ -360,6 +476,8 @@ enum {
};
static struct clk mstp_clks[MSTP_NR] = {
+ [MSTP128] = SH_CLK_MSTP32(&div4_clks[DIV4_S], SMSTPCR1, 28, 0), /* CEU21 */
+ [MSTP127] = SH_CLK_MSTP32(&div4_clks[DIV4_S], SMSTPCR1, 27, 0), /* CEU20 */
[MSTP125] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 25, 0), /* TMU0 */
[MSTP117] = SH_CLK_MSTP32(&div4_clks[DIV4_B], SMSTPCR1, 17, 0), /* LCDC1 */
[MSTP116] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR1, 16, 0), /* IIC0 */
@@ -368,6 +486,10 @@ static struct clk mstp_clks[MSTP_NR] = {
[MSTP230] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 30, 0), /* SCIFA6 */
[MSTP222] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 22, 0), /* SCIFA7 */
+ [MSTP218] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* DMAC1 */
+ [MSTP217] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* DMAC2 */
+ [MSTP216] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 16, 0), /* DMAC3 */
+ [MSTP214] = SH_CLK_MSTP32(&div4_clks[DIV4_HP], SMSTPCR2, 14, 0), /* USBDMAC */
[MSTP207] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
[MSTP206] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
[MSTP204] = SH_CLK_MSTP32(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
@@ -408,6 +530,12 @@ static struct clk_lookup lookups[] = {
CLKDEV_CON_ID("pllc1_clk", &pllc1_clk),
CLKDEV_CON_ID("pllc1_div2_clk", &pllc1_div2_clk),
CLKDEV_CON_ID("usb24s", &usb24s_clk),
+ CLKDEV_CON_ID("hdmi1", &hdmi1_clk),
+ CLKDEV_CON_ID("hdmi2", &hdmi2_clk),
+ CLKDEV_CON_ID("video1", &div6_reparent_clks[DIV6_VCLK1]),
+ CLKDEV_CON_ID("video2", &div6_reparent_clks[DIV6_VCLK2]),
+ CLKDEV_CON_ID("fsiack", &fsiack_clk),
+ CLKDEV_CON_ID("fsibck", &fsibck_clk),
/* DIV4 clocks */
CLKDEV_CON_ID("i_clk", &div4_clks[DIV4_I]),
@@ -430,6 +558,8 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("i2c-sh_mobile.0", &mstp_clks[MSTP116]),
CLKDEV_DEV_ID("sh_mobile_lcdc_fb.1", &mstp_clks[MSTP117]),
CLKDEV_DEV_ID("sh_tmu.0", &mstp_clks[MSTP125]),
+ CLKDEV_DEV_ID("sh_mobile_ceu.0", &mstp_clks[MSTP127]),
+ CLKDEV_DEV_ID("sh_mobile_ceu.1", &mstp_clks[MSTP128]),
CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]),
CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP201]),
@@ -438,7 +568,10 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]),
CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]),
CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]),
-
+ CLKDEV_DEV_ID("sh-dma-engine.3", &mstp_clks[MSTP214]),
+ CLKDEV_DEV_ID("sh-dma-engine.2", &mstp_clks[MSTP216]),
+ CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]),
+ CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]),
CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP222]),
CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP230]),
@@ -459,6 +592,10 @@ static struct clk_lookup lookups[] = {
CLKDEV_ICK_ID("phy", "renesas_usbhs", &mstp_clks[MSTP406]),
CLKDEV_ICK_ID("pci", "renesas_usbhs", &div4_clks[DIV4_USBP]),
CLKDEV_ICK_ID("usb24", "renesas_usbhs", &usb24_clk),
+ CLKDEV_ICK_ID("ick", "sh-mobile-hdmi", &div6_reparent_clks[DIV6_HDMI]),
+
+ CLKDEV_ICK_ID("icka", "sh_fsi2", &div6_reparent_clks[DIV6_FSIA]),
+ CLKDEV_ICK_ID("ickb", "sh_fsi2", &div6_reparent_clks[DIV6_FSIB]),
};
void __init r8a7740_clock_init(u8 md_ck)
@@ -495,7 +632,14 @@ void __init r8a7740_clock_init(u8 md_ck)
ret = sh_clk_div6_register(div6_clks, DIV6_NR);
if (!ret)
- ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+ ret = sh_clk_div6_reparent_register(div6_reparent_clks,
+ DIV6_REPARENT_NR);
+
+ if (!ret)
+ ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
+
+ for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
+ ret = clk_register(late_main_clks[k]);
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
diff --git a/arch/arm/mach-shmobile/clock-r8a7779.c b/arch/arm/mach-shmobile/clock-r8a7779.c
index 7d6e9fe47b5..339c62c824d 100644
--- a/arch/arm/mach-shmobile/clock-r8a7779.c
+++ b/arch/arm/mach-shmobile/clock-r8a7779.c
@@ -162,7 +162,7 @@ void __init r8a7779_clock_init(void)
ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
if (!ret)
- ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+ ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
ret = clk_register(late_main_clks[k]);
diff --git a/arch/arm/mach-shmobile/clock-sh7367.c b/arch/arm/mach-shmobile/clock-sh7367.c
index 006e7b5d304..162b791b898 100644
--- a/arch/arm/mach-shmobile/clock-sh7367.c
+++ b/arch/arm/mach-shmobile/clock-sh7367.c
@@ -344,7 +344,7 @@ void __init sh7367_clock_init(void)
ret = sh_clk_div6_register(div6_clks, DIV6_NR);
if (!ret)
- ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+ ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
diff --git a/arch/arm/mach-shmobile/clock-sh7372.c b/arch/arm/mach-shmobile/clock-sh7372.c
index 94d1f88246d..5a2894b1c96 100644
--- a/arch/arm/mach-shmobile/clock-sh7372.c
+++ b/arch/arm/mach-shmobile/clock-sh7372.c
@@ -704,7 +704,7 @@ void __init sh7372_clock_init(void)
ret = sh_clk_div6_reparent_register(div6_reparent_clks, DIV6_REPARENT_NR);
if (!ret)
- ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+ ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
ret = clk_register(late_main_clks[k]);
diff --git a/arch/arm/mach-shmobile/clock-sh7377.c b/arch/arm/mach-shmobile/clock-sh7377.c
index 0798a15936c..85f2a3ec2c4 100644
--- a/arch/arm/mach-shmobile/clock-sh7377.c
+++ b/arch/arm/mach-shmobile/clock-sh7377.c
@@ -355,7 +355,7 @@ void __init sh7377_clock_init(void)
ret = sh_clk_div6_register(div6_clks, DIV6_NR);
if (!ret)
- ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+ ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
clkdev_add_table(lookups, ARRAY_SIZE(lookups));
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 3946c4ba2aa..7f8da18a858 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -475,9 +475,9 @@ static struct clk *late_main_clks[] = {
enum { MSTP001,
MSTP129, MSTP128, MSTP127, MSTP126, MSTP125, MSTP118, MSTP116, MSTP100,
- MSTP219, MSTP218,
+ MSTP219, MSTP218, MSTP217,
MSTP207, MSTP206, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
- MSTP331, MSTP329, MSTP325, MSTP323,
+ MSTP331, MSTP329, MSTP328, MSTP325, MSTP323, MSTP322,
MSTP314, MSTP313, MSTP312, MSTP311,
MSTP303, MSTP302, MSTP301, MSTP300,
MSTP411, MSTP410, MSTP403,
@@ -498,6 +498,7 @@ static struct clk mstp_clks[MSTP_NR] = {
[MSTP100] = MSTP(&div4_clks[DIV4_B], SMSTPCR1, 0, 0), /* LCDC0 */
[MSTP219] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 19, 0), /* SCIFA7 */
[MSTP218] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 18, 0), /* SY-DMAC */
+ [MSTP217] = MSTP(&div4_clks[DIV4_HP], SMSTPCR2, 17, 0), /* MP-DMAC */
[MSTP207] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 7, 0), /* SCIFA5 */
[MSTP206] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 6, 0), /* SCIFB */
[MSTP204] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 4, 0), /* SCIFA0 */
@@ -507,8 +508,10 @@ static struct clk mstp_clks[MSTP_NR] = {
[MSTP200] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR2, 0, 0), /* SCIFA4 */
[MSTP331] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 31, 0), /* SCIFA6 */
[MSTP329] = MSTP(&r_clk, SMSTPCR3, 29, 0), /* CMT10 */
+ [MSTP328] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 28, 0), /*FSI*/
[MSTP325] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 25, 0), /* IrDA */
[MSTP323] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 23, 0), /* IIC1 */
+ [MSTP322] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 22, 0), /* USB */
[MSTP314] = MSTP(&div6_clks[DIV6_SDHI0], SMSTPCR3, 14, 0), /* SDHI0 */
[MSTP313] = MSTP(&div6_clks[DIV6_SDHI1], SMSTPCR3, 13, 0), /* SDHI1 */
[MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMCIF0 */
@@ -553,6 +556,7 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("sh_mobile_lcdc_fb.0", &mstp_clks[MSTP100]), /* LCDC0 */
CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP219]), /* SCIFA7 */
CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP218]), /* SY-DMAC */
+ CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP217]), /* MP-DMAC */
CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP207]), /* SCIFA5 */
CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP206]), /* SCIFB */
CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]), /* SCIFA0 */
@@ -562,8 +566,10 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP200]), /* SCIFA4 */
CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP331]), /* SCIFA6 */
CLKDEV_DEV_ID("sh_cmt.10", &mstp_clks[MSTP329]), /* CMT10 */
+ CLKDEV_DEV_ID("sh_fsi2", &mstp_clks[MSTP328]), /* FSI */
CLKDEV_DEV_ID("sh_irda.0", &mstp_clks[MSTP325]), /* IrDA */
CLKDEV_DEV_ID("i2c-sh_mobile.1", &mstp_clks[MSTP323]), /* I2C1 */
+ CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP322]), /* USB */
CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMCIF0 */
@@ -612,7 +618,7 @@ void __init sh73a0_clock_init(void)
ret = sh_clk_div6_reparent_register(div6_clks, DIV6_NR);
if (!ret)
- ret = sh_clk_mstp32_register(mstp_clks, MSTP_NR);
+ ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
for (k = 0; !ret && (k < ARRAY_SIZE(late_main_clks)); k++)
ret = clk_register(late_main_clks[k]);
diff --git a/arch/arm/mach-shmobile/include/mach/common.h b/arch/arm/mach-shmobile/include/mach/common.h
index 01e2bc014f1..45e61dada03 100644
--- a/arch/arm/mach-shmobile/include/mach/common.h
+++ b/arch/arm/mach-shmobile/include/mach/common.h
@@ -77,6 +77,7 @@ extern void r8a7779_add_standard_devices(void);
extern void r8a7779_clock_init(void);
extern void r8a7779_pinmux_init(void);
extern void r8a7779_pm_init(void);
+extern void r8a7740_meram_workaround(void);
extern unsigned int r8a7779_get_core_count(void);
extern int r8a7779_platform_cpu_kill(unsigned int cpu);
diff --git a/arch/arm/mach-shmobile/include/mach/dma-register.h b/arch/arm/mach-shmobile/include/mach/dma-register.h
new file mode 100644
index 00000000000..97c40bd9b94
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/dma-register.h
@@ -0,0 +1,84 @@
+/*
+ * SH-ARM CPU-specific DMA definitions, used by both DMA drivers
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp
+ *
+ * Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * Based on arch/sh/include/cpu-sh4/cpu/dma-register.h
+ * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef DMA_REGISTER_H
+#define DMA_REGISTER_H
+
+/*
+ * Direct Memory Access Controller
+ */
+
+/* Transmit sizes and respective CHCR register values */
+enum {
+ XMIT_SZ_8BIT = 0,
+ XMIT_SZ_16BIT = 1,
+ XMIT_SZ_32BIT = 2,
+ XMIT_SZ_64BIT = 7,
+ XMIT_SZ_128BIT = 3,
+ XMIT_SZ_256BIT = 4,
+ XMIT_SZ_512BIT = 5,
+};
+
+/* log2(size / 8) - used to calculate number of transfers */
+static const unsigned int dma_ts_shift[] = {
+ [XMIT_SZ_8BIT] = 0,
+ [XMIT_SZ_16BIT] = 1,
+ [XMIT_SZ_32BIT] = 2,
+ [XMIT_SZ_64BIT] = 3,
+ [XMIT_SZ_128BIT] = 4,
+ [XMIT_SZ_256BIT] = 5,
+ [XMIT_SZ_512BIT] = 6,
+};
+
+#define TS_LOW_BIT 0x3 /* --xx */
+#define TS_HI_BIT 0xc /* xx-- */
+
+#define TS_LOW_SHIFT (3)
+#define TS_HI_SHIFT (20 - 2) /* 2 bits for shifted low TS */
+
+#define TS_INDEX2VAL(i) \
+ ((((i) & TS_LOW_BIT) << TS_LOW_SHIFT) |\
+ (((i) & TS_HI_BIT) << TS_HI_SHIFT))
+
+#define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL((xmit_sz)))
+#define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL((xmit_sz)))
+
+
+/*
+ * USB High-Speed DMAC
+ */
+/* Transmit sizes and respective CHCR register values */
+enum {
+ USBTS_XMIT_SZ_8BYTE = 0,
+ USBTS_XMIT_SZ_16BYTE = 1,
+ USBTS_XMIT_SZ_32BYTE = 2,
+};
+
+/* log2(size / 8) - used to calculate number of transfers */
+static const unsigned int dma_usbts_shift[] = {
+ [USBTS_XMIT_SZ_8BYTE] = 3,
+ [USBTS_XMIT_SZ_16BYTE] = 4,
+ [USBTS_XMIT_SZ_32BYTE] = 5,
+};
+
+#define USBTS_LOW_BIT 0x3 /* --xx */
+#define USBTS_HI_BIT 0x0 /* ---- */
+
+#define USBTS_LOW_SHIFT 6
+#define USBTS_HI_SHIFT 0
+
+#define USBTS_INDEX2VAL(i) (((i) & 3) << 6)
+
+#endif /* DMA_REGISTER_H */
diff --git a/arch/arm/mach-shmobile/include/mach/gpio.h b/arch/arm/mach-shmobile/include/mach/gpio.h
index de795b42232..844507d937c 100644
--- a/arch/arm/mach-shmobile/include/mach/gpio.h
+++ b/arch/arm/mach-shmobile/include/mach/gpio.h
@@ -13,6 +13,7 @@
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/sh_pfc.h>
+#include <linux/io.h>
#ifdef CONFIG_GPIOLIB
@@ -27,4 +28,35 @@ static inline int irq_to_gpio(unsigned int irq)
#endif /* CONFIG_GPIOLIB */
+/*
+ * FIXME !!
+ *
+ * current gpio frame work doesn't have
+ * the method to control only pull up/down/free.
+ * this function should be replaced by correct gpio function
+ */
+static inline void __init gpio_direction_none(u32 addr)
+{
+ __raw_writeb(0x00, addr);
+}
+
+static inline void __init gpio_request_pullup(u32 addr)
+{
+ u8 data = __raw_readb(addr);
+
+ data &= 0x0F;
+ data |= 0xC0;
+ __raw_writeb(data, addr);
+}
+
+static inline void __init gpio_request_pulldown(u32 addr)
+{
+ u8 data = __raw_readb(addr);
+
+ data &= 0x0F;
+ data |= 0xA0;
+
+ __raw_writeb(data, addr);
+}
+
#endif /* __ASM_ARCH_GPIO_H */
diff --git a/arch/arm/mach-shmobile/include/mach/pm-rmobile.h b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h
new file mode 100644
index 00000000000..5a402840fe2
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/pm-rmobile.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ *
+ * Kuninori Morimoto <morimoto.kuninori@renesas.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#ifndef PM_RMOBILE_H
+#define PM_RMOBILE_H
+
+#include <linux/pm_domain.h>
+
+struct platform_device;
+
+struct rmobile_pm_domain {
+ struct generic_pm_domain genpd;
+ struct dev_power_governor *gov;
+ int (*suspend)(void);
+ void (*resume)(void);
+ unsigned int bit_shift;
+ bool no_debug;
+};
+
+static inline
+struct rmobile_pm_domain *to_rmobile_pd(struct generic_pm_domain *d)
+{
+ return container_of(d, struct rmobile_pm_domain, genpd);
+}
+
+#ifdef CONFIG_PM
+extern void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd);
+extern void rmobile_add_device_to_domain(struct rmobile_pm_domain *rmobile_pd,
+ struct platform_device *pdev);
+extern void rmobile_pm_add_subdomain(struct rmobile_pm_domain *rmobile_pd,
+ struct rmobile_pm_domain *rmobile_sd);
+#else
+#define rmobile_init_pm_domain(pd) do { } while (0)
+#define rmobile_add_device_to_domain(pd, pdev) do { } while (0)
+#define rmobile_pm_add_subdomain(pd, sd) do { } while (0)
+#endif /* CONFIG_PM */
+
+#endif /* PM_RMOBILE_H */
diff --git a/arch/arm/mach-shmobile/include/mach/r8a7740.h b/arch/arm/mach-shmobile/include/mach/r8a7740.h
index 9d447abb969..7143147780d 100644
--- a/arch/arm/mach-shmobile/include/mach/r8a7740.h
+++ b/arch/arm/mach-shmobile/include/mach/r8a7740.h
@@ -19,6 +19,8 @@
#ifndef __ASM_R8A7740_H__
#define __ASM_R8A7740_H__
+#include <mach/pm-rmobile.h>
+
/*
* MD_CKx pin
*/
@@ -139,7 +141,7 @@ enum {
GPIO_FN_DBGMD10, GPIO_FN_DBGMD11, GPIO_FN_DBGMD20,
GPIO_FN_DBGMD21,
- /* FSI */
+ /* FSI-A */
GPIO_FN_FSIAISLD_PORT0, /* FSIAISLD Port 0/5 */
GPIO_FN_FSIAISLD_PORT5,
GPIO_FN_FSIASPDIF_PORT9, /* FSIASPDIF Port 9/18 */
@@ -150,6 +152,9 @@ enum {
GPIO_FN_FSIACK, GPIO_FN_FSIAILR,
GPIO_FN_FSIAIBT,
+ /* FSI-B */
+ GPIO_FN_FSIBCK,
+
/* FMSI */
GPIO_FN_FMSISLD_PORT1, /* FMSISLD Port 1/6 */
GPIO_FN_FMSISLD_PORT6,
@@ -565,6 +570,10 @@ enum {
GPIO_FN_RESETP_PULLUP,
GPIO_FN_RESETP_PLAIN,
+ /* HDMI */
+ GPIO_FN_HDMI_HPD,
+ GPIO_FN_HDMI_CEC,
+
/* SDENC */
GPIO_FN_SDENC_CPG,
GPIO_FN_SDENC_DV_CLKI,
@@ -581,4 +590,26 @@ enum {
GPIO_FN_TRACEAUD_FROM_MEMC,
};
+/* DMA slave IDs */
+enum {
+ SHDMA_SLAVE_INVALID,
+ SHDMA_SLAVE_SDHI0_RX,
+ SHDMA_SLAVE_SDHI0_TX,
+ SHDMA_SLAVE_SDHI1_RX,
+ SHDMA_SLAVE_SDHI1_TX,
+ SHDMA_SLAVE_SDHI2_RX,
+ SHDMA_SLAVE_SDHI2_TX,
+ SHDMA_SLAVE_FSIA_RX,
+ SHDMA_SLAVE_FSIA_TX,
+ SHDMA_SLAVE_FSIB_TX,
+ SHDMA_SLAVE_USBHS_TX,
+ SHDMA_SLAVE_USBHS_RX,
+};
+
+#ifdef CONFIG_PM
+extern struct rmobile_pm_domain r8a7740_pd_a4s;
+extern struct rmobile_pm_domain r8a7740_pd_a3sp;
+extern struct rmobile_pm_domain r8a7740_pd_a4lc;
+#endif /* CONFIG_PM */
+
#endif /* __ASM_R8A7740_H__ */
diff --git a/arch/arm/mach-shmobile/include/mach/sh7372.h b/arch/arm/mach-shmobile/include/mach/sh7372.h
index 915d0093da0..b59048e6d8f 100644
--- a/arch/arm/mach-shmobile/include/mach/sh7372.h
+++ b/arch/arm/mach-shmobile/include/mach/sh7372.h
@@ -13,6 +13,7 @@
#include <linux/sh_clk.h>
#include <linux/pm_domain.h>
+#include <mach/pm-rmobile.h>
/*
* Pin Function Controller:
@@ -477,42 +478,16 @@ extern struct clk sh7372_fsibck_clk;
extern struct clk sh7372_fsidiva_clk;
extern struct clk sh7372_fsidivb_clk;
-struct platform_device;
-
-struct sh7372_pm_domain {
- struct generic_pm_domain genpd;
- struct dev_power_governor *gov;
- int (*suspend)(void);
- void (*resume)(void);
- unsigned int bit_shift;
- bool no_debug;
-};
-
-static inline struct sh7372_pm_domain *to_sh7372_pd(struct generic_pm_domain *d)
-{
- return container_of(d, struct sh7372_pm_domain, genpd);
-}
-
#ifdef CONFIG_PM
-extern struct sh7372_pm_domain sh7372_a4lc;
-extern struct sh7372_pm_domain sh7372_a4mp;
-extern struct sh7372_pm_domain sh7372_d4;
-extern struct sh7372_pm_domain sh7372_a4r;
-extern struct sh7372_pm_domain sh7372_a3rv;
-extern struct sh7372_pm_domain sh7372_a3ri;
-extern struct sh7372_pm_domain sh7372_a4s;
-extern struct sh7372_pm_domain sh7372_a3sp;
-extern struct sh7372_pm_domain sh7372_a3sg;
-
-extern void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd);
-extern void sh7372_add_device_to_domain(struct sh7372_pm_domain *sh7372_pd,
- struct platform_device *pdev);
-extern void sh7372_pm_add_subdomain(struct sh7372_pm_domain *sh7372_pd,
- struct sh7372_pm_domain *sh7372_sd);
-#else
-#define sh7372_init_pm_domain(pd) do { } while(0)
-#define sh7372_add_device_to_domain(pd, pdev) do { } while(0)
-#define sh7372_pm_add_subdomain(pd, sd) do { } while(0)
+extern struct rmobile_pm_domain sh7372_pd_a4lc;
+extern struct rmobile_pm_domain sh7372_pd_a4mp;
+extern struct rmobile_pm_domain sh7372_pd_d4;
+extern struct rmobile_pm_domain sh7372_pd_a4r;
+extern struct rmobile_pm_domain sh7372_pd_a3rv;
+extern struct rmobile_pm_domain sh7372_pd_a3ri;
+extern struct rmobile_pm_domain sh7372_pd_a4s;
+extern struct rmobile_pm_domain sh7372_pd_a3sp;
+extern struct rmobile_pm_domain sh7372_pd_a3sg;
#endif /* CONFIG_PM */
extern void sh7372_intcs_suspend(void);
diff --git a/arch/arm/mach-shmobile/include/mach/sh73a0.h b/arch/arm/mach-shmobile/include/mach/sh73a0.h
index 398e2c10913..fe950f25d79 100644
--- a/arch/arm/mach-shmobile/include/mach/sh73a0.h
+++ b/arch/arm/mach-shmobile/include/mach/sh73a0.h
@@ -516,6 +516,13 @@ enum {
SHDMA_SLAVE_SDHI2_RX,
SHDMA_SLAVE_MMCIF_TX,
SHDMA_SLAVE_MMCIF_RX,
+ SHDMA_SLAVE_FSI2A_TX,
+ SHDMA_SLAVE_FSI2A_RX,
+ SHDMA_SLAVE_FSI2B_TX,
+ SHDMA_SLAVE_FSI2B_RX,
+ SHDMA_SLAVE_FSI2C_TX,
+ SHDMA_SLAVE_FSI2C_RX,
+ SHDMA_SLAVE_FSI2D_RX,
};
/*
diff --git a/arch/arm/mach-shmobile/intc-r8a7740.c b/arch/arm/mach-shmobile/intc-r8a7740.c
index 09c42afcb22..9a69a31918b 100644
--- a/arch/arm/mach-shmobile/intc-r8a7740.c
+++ b/arch/arm/mach-shmobile/intc-r8a7740.c
@@ -71,10 +71,12 @@ enum {
DMAC3_1_DEI0, DMAC3_1_DEI1, DMAC3_1_DEI2, DMAC3_1_DEI3,
DMAC3_2_DEI4, DMAC3_2_DEI5, DMAC3_2_DADERR,
SHWYSTAT_RT, SHWYSTAT_HS, SHWYSTAT_COM,
+ HDMI,
USBH_INT, USBH_OHCI, USBH_EHCI, USBH_PME, USBH_BIND,
RSPI_OVRF, RSPI_SPTEF, RSPI_SPRF,
SPU2_0, SPU2_1,
FSI, FMSI,
+ HDMI_SSS, HDMI_KEY,
IPMMU,
AP_ARM_CTIIRQ, AP_ARM_PMURQ,
MFIS2,
@@ -182,6 +184,7 @@ static struct intc_vect intca_vectors[] __initdata = {
INTC_VECT(USBH_EHCI, 0x1580),
INTC_VECT(USBH_PME, 0x15A0),
INTC_VECT(USBH_BIND, 0x15C0),
+ INTC_VECT(HDMI, 0x1700),
INTC_VECT(RSPI_OVRF, 0x1780),
INTC_VECT(RSPI_SPTEF, 0x17A0),
INTC_VECT(RSPI_SPRF, 0x17C0),
@@ -189,6 +192,8 @@ static struct intc_vect intca_vectors[] __initdata = {
INTC_VECT(SPU2_1, 0x1820),
INTC_VECT(FSI, 0x1840),
INTC_VECT(FMSI, 0x1860),
+ INTC_VECT(HDMI_SSS, 0x18A0),
+ INTC_VECT(HDMI_KEY, 0x18C0),
INTC_VECT(IPMMU, 0x1920),
INTC_VECT(AP_ARM_CTIIRQ, 0x1980),
INTC_VECT(AP_ARM_PMURQ, 0x19A0),
@@ -304,11 +309,11 @@ static struct intc_mask_reg intca_mask_registers[] __initdata = {
USBH_EHCI, USBH_PME, USBH_BIND, 0 } },
/* IMR3A3 / IMCR3A3 */
{ /* IMR4A3 / IMCR4A3 */ 0xe6950090, 0xe69500d0, 8,
- { 0, 0, 0, 0,
+ { HDMI, 0, 0, 0,
RSPI_OVRF, RSPI_SPTEF, RSPI_SPRF, 0 } },
{ /* IMR5A3 / IMCR5A3 */ 0xe6950094, 0xe69500d4, 8,
{ SPU2_0, SPU2_1, FSI, FMSI,
- 0, 0, 0, 0 } },
+ 0, HDMI_SSS, HDMI_KEY, 0 } },
{ /* IMR6A3 / IMCR6A3 */ 0xe6950098, 0xe69500d8, 8,
{ 0, IPMMU, 0, 0,
AP_ARM_CTIIRQ, AP_ARM_PMURQ, 0, 0 } },
@@ -353,10 +358,10 @@ static struct intc_prio_reg intca_prio_registers[] __initdata = {
{ 0xe6950014, 0, 16, 4, /* IPRFA3 */ { USBH2, 0, 0, 0 } },
/* IPRGA3 */
/* IPRHA3 */
- /* IPRIA3 */
+ { 0xe6950020, 0, 16, 4, /* IPRIA3 */ { HDMI, 0, 0, 0 } },
{ 0xe6950024, 0, 16, 4, /* IPRJA3 */ { RSPI, 0, 0, 0 } },
{ 0xe6950028, 0, 16, 4, /* IPRKA3 */ { SPU2, 0, FSI, FMSI } },
- /* IPRLA3 */
+ { 0xe695002c, 0, 16, 4, /* IPRLA3 */ { 0, HDMI_SSS, HDMI_KEY, 0 } },
{ 0xe6950030, 0, 16, 4, /* IPRMA3 */ { IPMMU, 0, 0, 0 } },
{ 0xe6950034, 0, 16, 4, /* IPRNA3 */ { AP_ARM2, 0, 0, 0 } },
{ 0xe6950038, 0, 16, 4, /* IPROA3 */ { MFIS2, CPORTR2S,
diff --git a/arch/arm/mach-shmobile/pfc-r8a7740.c b/arch/arm/mach-shmobile/pfc-r8a7740.c
index 670fe1869db..ce9e7fa5cc8 100644
--- a/arch/arm/mach-shmobile/pfc-r8a7740.c
+++ b/arch/arm/mach-shmobile/pfc-r8a7740.c
@@ -169,7 +169,7 @@ enum {
DBGMD10_MARK, DBGMD11_MARK, DBGMD20_MARK,
DBGMD21_MARK,
- /* FSI */
+ /* FSI-A */
FSIAISLD_PORT0_MARK, /* FSIAISLD Port 0/5 */
FSIAISLD_PORT5_MARK,
FSIASPDIF_PORT9_MARK, /* FSIASPDIF Port 9/18 */
@@ -178,6 +178,9 @@ enum {
FSIAOBT_MARK, FSIAOSLD_MARK, FSIAOMC_MARK,
FSIACK_MARK, FSIAILR_MARK, FSIAIBT_MARK,
+ /* FSI-B */
+ FSIBCK_MARK,
+
/* FMSI */
FMSISLD_PORT1_MARK, /* FMSISLD Port 1/6 */
FMSISLD_PORT6_MARK,
@@ -560,6 +563,9 @@ enum {
/* SDENC */
SDENC_CPG_MARK, SDENC_DV_CLKI_MARK,
+ /* HDMI */
+ HDMI_HPD_MARK, HDMI_CEC_MARK,
+
/* DEBUG */
EDEBGREQ_PULLUP_MARK, /* for JTAG */
EDEBGREQ_PULLDOWN_MARK,
@@ -771,6 +777,7 @@ static pinmux_enum_t pinmux_data[] = {
/* Port11 */
PINMUX_DATA(FSIACK_MARK, PORT11_FN1),
+ PINMUX_DATA(FSIBCK_MARK, PORT11_FN2),
PINMUX_DATA(IRQ2_PORT11_MARK, PORT11_FN0, MSEL1CR_2_0),
/* Port12 */
@@ -1254,7 +1261,7 @@ static pinmux_enum_t pinmux_data[] = {
PINMUX_DATA(A21_MARK, PORT120_FN1),
PINMUX_DATA(MSIOF0_RSYNC_MARK, PORT120_FN2),
PINMUX_DATA(MSIOF1_TSYNC_PORT120_MARK, PORT120_FN3, MSEL4CR_10_0),
- PINMUX_DATA(IRQ7_PORT120_MARK, PORT120_FN0, MSEL1CR_7_0),
+ PINMUX_DATA(IRQ7_PORT120_MARK, PORT120_FN0, MSEL1CR_7_1),
/* Port121 */
PINMUX_DATA(A20_MARK, PORT121_FN1),
@@ -1616,13 +1623,15 @@ static pinmux_enum_t pinmux_data[] = {
/* Port209 */
PINMUX_DATA(VBUS_MARK, PORT209_FN1),
- PINMUX_DATA(IRQ7_PORT209_MARK, PORT209_FN0, MSEL1CR_7_1),
+ PINMUX_DATA(IRQ7_PORT209_MARK, PORT209_FN0, MSEL1CR_7_0),
/* Port210 */
PINMUX_DATA(IRQ9_PORT210_MARK, PORT210_FN0, MSEL1CR_9_1),
+ PINMUX_DATA(HDMI_HPD_MARK, PORT210_FN1),
/* Port211 */
PINMUX_DATA(IRQ16_PORT211_MARK, PORT211_FN0, MSEL1CR_16_1),
+ PINMUX_DATA(HDMI_CEC_MARK, PORT211_FN1),
/* LCDC select */
PINMUX_DATA(LCDC0_SELECT_MARK, MSEL3CR_6_0),
@@ -1691,7 +1700,7 @@ static struct pinmux_gpio pinmux_gpios[] = {
GPIO_FN(DBGMD10), GPIO_FN(DBGMD11), GPIO_FN(DBGMD20),
GPIO_FN(DBGMD21),
- /* FSI */
+ /* FSI-A */
GPIO_FN(FSIAISLD_PORT0), /* FSIAISLD Port 0/5 */
GPIO_FN(FSIAISLD_PORT5),
GPIO_FN(FSIASPDIF_PORT9), /* FSIASPDIF Port 9/18 */
@@ -1700,6 +1709,9 @@ static struct pinmux_gpio pinmux_gpios[] = {
GPIO_FN(FSIAOBT), GPIO_FN(FSIAOSLD), GPIO_FN(FSIAOMC),
GPIO_FN(FSIACK), GPIO_FN(FSIAILR), GPIO_FN(FSIAIBT),
+ /* FSI-B */
+ GPIO_FN(FSIBCK),
+
/* FMSI */
GPIO_FN(FMSISLD_PORT1), /* FMSISLD Port 1/6 */
GPIO_FN(FMSISLD_PORT6),
@@ -2097,6 +2109,10 @@ static struct pinmux_gpio pinmux_gpios[] = {
GPIO_FN(SDENC_CPG),
GPIO_FN(SDENC_DV_CLKI),
+ /* HDMI */
+ GPIO_FN(HDMI_HPD),
+ GPIO_FN(HDMI_CEC),
+
/* SYSC */
GPIO_FN(RESETP_PULLUP),
GPIO_FN(RESETP_PLAIN),
diff --git a/arch/arm/mach-shmobile/pm-r8a7740.c b/arch/arm/mach-shmobile/pm-r8a7740.c
new file mode 100644
index 00000000000..893504d012a
--- /dev/null
+++ b/arch/arm/mach-shmobile/pm-r8a7740.c
@@ -0,0 +1,54 @@
+/*
+ * r8a7740 power management support
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+#include <linux/console.h>
+#include <mach/pm-rmobile.h>
+
+#ifdef CONFIG_PM
+static int r8a7740_pd_a4s_suspend(void)
+{
+ /*
+ * The A4S domain contains the CPU core and therefore it should
+ * only be turned off if the CPU is in use.
+ */
+ return -EBUSY;
+}
+
+struct rmobile_pm_domain r8a7740_pd_a4s = {
+ .genpd.name = "A4S",
+ .bit_shift = 10,
+ .gov = &pm_domain_always_on_gov,
+ .no_debug = true,
+ .suspend = r8a7740_pd_a4s_suspend,
+};
+
+static int r8a7740_pd_a3sp_suspend(void)
+{
+ /*
+ * Serial consoles make use of SCIF hardware located in A3SP,
+ * keep such power domain on if "no_console_suspend" is set.
+ */
+ return console_suspend_enabled ? 0 : -EBUSY;
+}
+
+struct rmobile_pm_domain r8a7740_pd_a3sp = {
+ .genpd.name = "A3SP",
+ .bit_shift = 11,
+ .gov = &pm_domain_always_on_gov,
+ .no_debug = true,
+ .suspend = r8a7740_pd_a3sp_suspend,
+};
+
+struct rmobile_pm_domain r8a7740_pd_a4lc = {
+ .genpd.name = "A4LC",
+ .bit_shift = 1,
+};
+
+#endif /* CONFIG_PM */
diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c
new file mode 100644
index 00000000000..a8562540f1d
--- /dev/null
+++ b/arch/arm/mach-shmobile/pm-rmobile.c
@@ -0,0 +1,167 @@
+/*
+ * rmobile power management support
+ *
+ * Copyright (C) 2012 Renesas Solutions Corp.
+ * Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ *
+ * based on pm-sh7372.c
+ * Copyright (C) 2011 Magnus Damm
+ *
+ * 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/console.h>
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/pm_clock.h>
+#include <asm/io.h>
+#include <mach/pm-rmobile.h>
+
+/* SYSC */
+#define SPDCR 0xe6180008
+#define SWUCR 0xe6180014
+#define PSTR 0xe6180080
+
+#define PSTR_RETRIES 100
+#define PSTR_DELAY_US 10
+
+#ifdef CONFIG_PM
+static int rmobile_pd_power_down(struct generic_pm_domain *genpd)
+{
+ struct rmobile_pm_domain *rmobile_pd = to_rmobile_pd(genpd);
+ unsigned int mask = 1 << rmobile_pd->bit_shift;
+
+ if (rmobile_pd->suspend) {
+ int ret = rmobile_pd->suspend();
+
+ if (ret)
+ return ret;
+ }
+
+ if (__raw_readl(PSTR) & mask) {
+ unsigned int retry_count;
+ __raw_writel(mask, SPDCR);
+
+ for (retry_count = PSTR_RETRIES; retry_count; retry_count--) {
+ if (!(__raw_readl(SPDCR) & mask))
+ break;
+ cpu_relax();
+ }
+ }
+
+ if (!rmobile_pd->no_debug)
+ pr_debug("%s: Power off, 0x%08x -> PSTR = 0x%08x\n",
+ genpd->name, mask, __raw_readl(PSTR));
+
+ return 0;
+}
+
+static int __rmobile_pd_power_up(struct rmobile_pm_domain *rmobile_pd,
+ bool do_resume)
+{
+ unsigned int mask = 1 << rmobile_pd->bit_shift;
+ unsigned int retry_count;
+ int ret = 0;
+
+ if (__raw_readl(PSTR) & mask)
+ goto out;
+
+ __raw_writel(mask, SWUCR);
+
+ for (retry_count = 2 * PSTR_RETRIES; retry_count; retry_count--) {
+ if (!(__raw_readl(SWUCR) & mask))
+ break;
+ if (retry_count > PSTR_RETRIES)
+ udelay(PSTR_DELAY_US);
+ else
+ cpu_relax();
+ }
+ if (!retry_count)
+ ret = -EIO;
+
+ if (!rmobile_pd->no_debug)
+ pr_debug("%s: Power on, 0x%08x -> PSTR = 0x%08x\n",
+ rmobile_pd->genpd.name, mask, __raw_readl(PSTR));
+
+out:
+ if (ret == 0 && rmobile_pd->resume && do_resume)
+ rmobile_pd->resume();
+
+ return ret;
+}
+
+static int rmobile_pd_power_up(struct generic_pm_domain *genpd)
+{
+ return __rmobile_pd_power_up(to_rmobile_pd(genpd), true);
+}
+
+static bool rmobile_pd_active_wakeup(struct device *dev)
+{
+ bool (*active_wakeup)(struct device *dev);
+
+ active_wakeup = dev_gpd_data(dev)->ops.active_wakeup;
+ return active_wakeup ? active_wakeup(dev) : true;
+}
+
+static int rmobile_pd_stop_dev(struct device *dev)
+{
+ int (*stop)(struct device *dev);
+
+ stop = dev_gpd_data(dev)->ops.stop;
+ if (stop) {
+ int ret = stop(dev);
+ if (ret)
+ return ret;
+ }
+ return pm_clk_suspend(dev);
+}
+
+static int rmobile_pd_start_dev(struct device *dev)
+{
+ int (*start)(struct device *dev);
+ int ret;
+
+ ret = pm_clk_resume(dev);
+ if (ret)
+ return ret;
+
+ start = dev_gpd_data(dev)->ops.start;
+ if (start)
+ ret = start(dev);
+
+ return ret;
+}
+
+void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
+{
+ struct generic_pm_domain *genpd = &rmobile_pd->genpd;
+ struct dev_power_governor *gov = rmobile_pd->gov;
+
+ pm_genpd_init(genpd, gov ? : &simple_qos_governor, false);
+ genpd->dev_ops.stop = rmobile_pd_stop_dev;
+ genpd->dev_ops.start = rmobile_pd_start_dev;
+ genpd->dev_ops.active_wakeup = rmobile_pd_active_wakeup;
+ genpd->dev_irq_safe = true;
+ genpd->power_off = rmobile_pd_power_down;
+ genpd->power_on = rmobile_pd_power_up;
+ __rmobile_pd_power_up(rmobile_pd, false);
+}
+
+void rmobile_add_device_to_domain(struct rmobile_pm_domain *rmobile_pd,
+ struct platform_device *pdev)
+{
+ struct device *dev = &pdev->dev;
+
+ pm_genpd_add_device(&rmobile_pd->genpd, dev);
+ if (pm_clk_no_clocks(dev))
+ pm_clk_add(dev, NULL);
+}
+
+void rmobile_pm_add_subdomain(struct rmobile_pm_domain *rmobile_pd,
+ struct rmobile_pm_domain *rmobile_sd)
+{
+ pm_genpd_add_subdomain(&rmobile_pd->genpd, &rmobile_sd->genpd);
+}
+#endif /* CONFIG_PM */
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c
index a3bdb12acde..79203706922 100644
--- a/arch/arm/mach-shmobile/pm-sh7372.c
+++ b/arch/arm/mach-shmobile/pm-sh7372.c
@@ -26,6 +26,7 @@
#include <asm/suspend.h>
#include <mach/common.h>
#include <mach/sh7372.h>
+#include <mach/pm-rmobile.h>
/* DBG */
#define DBGREG1 0xe6100020
@@ -41,13 +42,10 @@
#define PLLC01STPCR 0xe61500c8
/* SYSC */
-#define SPDCR 0xe6180008
-#define SWUCR 0xe6180014
#define SBAR 0xe6180020
#define WUPRMSK 0xe6180028
#define WUPSMSK 0xe618002c
#define WUPSMSK2 0xe6180048
-#define PSTR 0xe6180080
#define WUPSFAC 0xe6180098
#define IRQCR 0xe618022c
#define IRQCR2 0xe6180238
@@ -71,188 +69,48 @@
/* AP-System Core */
#define APARMBAREA 0xe6f10020
-#define PSTR_RETRIES 100
-#define PSTR_DELAY_US 10
-
#ifdef CONFIG_PM
-static int pd_power_down(struct generic_pm_domain *genpd)
-{
- struct sh7372_pm_domain *sh7372_pd = to_sh7372_pd(genpd);
- unsigned int mask = 1 << sh7372_pd->bit_shift;
-
- if (sh7372_pd->suspend) {
- int ret = sh7372_pd->suspend();
-
- if (ret)
- return ret;
- }
-
- if (__raw_readl(PSTR) & mask) {
- unsigned int retry_count;
-
- __raw_writel(mask, SPDCR);
-
- for (retry_count = PSTR_RETRIES; retry_count; retry_count--) {
- if (!(__raw_readl(SPDCR) & mask))
- break;
- cpu_relax();
- }
- }
-
- if (!sh7372_pd->no_debug)
- pr_debug("%s: Power off, 0x%08x -> PSTR = 0x%08x\n",
- genpd->name, mask, __raw_readl(PSTR));
-
- return 0;
-}
-
-static int __pd_power_up(struct sh7372_pm_domain *sh7372_pd, bool do_resume)
-{
- unsigned int mask = 1 << sh7372_pd->bit_shift;
- unsigned int retry_count;
- int ret = 0;
-
- if (__raw_readl(PSTR) & mask)
- goto out;
-
- __raw_writel(mask, SWUCR);
-
- for (retry_count = 2 * PSTR_RETRIES; retry_count; retry_count--) {
- if (!(__raw_readl(SWUCR) & mask))
- break;
- if (retry_count > PSTR_RETRIES)
- udelay(PSTR_DELAY_US);
- else
- cpu_relax();
- }
- if (!retry_count)
- ret = -EIO;
-
- if (!sh7372_pd->no_debug)
- pr_debug("%s: Power on, 0x%08x -> PSTR = 0x%08x\n",
- sh7372_pd->genpd.name, mask, __raw_readl(PSTR));
-
- out:
- if (ret == 0 && sh7372_pd->resume && do_resume)
- sh7372_pd->resume();
-
- return ret;
-}
-
-static int pd_power_up(struct generic_pm_domain *genpd)
-{
- return __pd_power_up(to_sh7372_pd(genpd), true);
-}
-
-static int sh7372_a4r_suspend(void)
-{
- sh7372_intcs_suspend();
- __raw_writel(0x300fffff, WUPRMSK); /* avoid wakeup */
- return 0;
-}
-
-static bool pd_active_wakeup(struct device *dev)
-{
- bool (*active_wakeup)(struct device *dev);
-
- active_wakeup = dev_gpd_data(dev)->ops.active_wakeup;
- return active_wakeup ? active_wakeup(dev) : true;
-}
-
-static int sh7372_stop_dev(struct device *dev)
-{
- int (*stop)(struct device *dev);
-
- stop = dev_gpd_data(dev)->ops.stop;
- if (stop) {
- int ret = stop(dev);
- if (ret)
- return ret;
- }
- return pm_clk_suspend(dev);
-}
-
-static int sh7372_start_dev(struct device *dev)
-{
- int (*start)(struct device *dev);
- int ret;
-
- ret = pm_clk_resume(dev);
- if (ret)
- return ret;
-
- start = dev_gpd_data(dev)->ops.start;
- if (start)
- ret = start(dev);
-
- return ret;
-}
-
-void sh7372_init_pm_domain(struct sh7372_pm_domain *sh7372_pd)
-{
- struct generic_pm_domain *genpd = &sh7372_pd->genpd;
- struct dev_power_governor *gov = sh7372_pd->gov;
-
- pm_genpd_init(genpd, gov ? : &simple_qos_governor, false);
- genpd->dev_ops.stop = sh7372_stop_dev;
- genpd->dev_ops.start = sh7372_start_dev;
- genpd->dev_ops.active_wakeup = pd_active_wakeup;
- genpd->dev_irq_safe = true;
- genpd->power_off = pd_power_down;
- genpd->power_on = pd_power_up;
- __pd_power_up(sh7372_pd, false);
-}
-
-void sh7372_add_device_to_domain(struct sh7372_pm_domain *sh7372_pd,
- struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
-
- pm_genpd_add_device(&sh7372_pd->genpd, dev);
- if (pm_clk_no_clocks(dev))
- pm_clk_add(dev, NULL);
-}
-
-void sh7372_pm_add_subdomain(struct sh7372_pm_domain *sh7372_pd,
- struct sh7372_pm_domain *sh7372_sd)
-{
- pm_genpd_add_subdomain(&sh7372_pd->genpd, &sh7372_sd->genpd);
-}
-
-struct sh7372_pm_domain sh7372_a4lc = {
+struct rmobile_pm_domain sh7372_pd_a4lc = {
.genpd.name = "A4LC",
.bit_shift = 1,
};
-struct sh7372_pm_domain sh7372_a4mp = {
+struct rmobile_pm_domain sh7372_pd_a4mp = {
.genpd.name = "A4MP",
.bit_shift = 2,
};
-struct sh7372_pm_domain sh7372_d4 = {
+struct rmobile_pm_domain sh7372_pd_d4 = {
.genpd.name = "D4",
.bit_shift = 3,
};
-struct sh7372_pm_domain sh7372_a4r = {
+static int sh7372_a4r_pd_suspend(void)
+{
+ sh7372_intcs_suspend();
+ __raw_writel(0x300fffff, WUPRMSK); /* avoid wakeup */
+ return 0;
+}
+
+struct rmobile_pm_domain sh7372_pd_a4r = {
.genpd.name = "A4R",
.bit_shift = 5,
- .suspend = sh7372_a4r_suspend,
+ .suspend = sh7372_a4r_pd_suspend,
.resume = sh7372_intcs_resume,
};
-struct sh7372_pm_domain sh7372_a3rv = {
+struct rmobile_pm_domain sh7372_pd_a3rv = {
.genpd.name = "A3RV",
.bit_shift = 6,
};
-struct sh7372_pm_domain sh7372_a3ri = {
+struct rmobile_pm_domain sh7372_pd_a3ri = {
.genpd.name = "A3RI",
.bit_shift = 8,
};
-static int sh7372_a4s_suspend(void)
+static int sh7372_pd_a4s_suspend(void)
{
/*
* The A4S domain contains the CPU core and therefore it should
@@ -261,15 +119,15 @@ static int sh7372_a4s_suspend(void)
return -EBUSY;
}
-struct sh7372_pm_domain sh7372_a4s = {
+struct rmobile_pm_domain sh7372_pd_a4s = {
.genpd.name = "A4S",
.bit_shift = 10,
.gov = &pm_domain_always_on_gov,
.no_debug = true,
- .suspend = sh7372_a4s_suspend,
+ .suspend = sh7372_pd_a4s_suspend,
};
-static int sh7372_a3sp_suspend(void)
+static int sh7372_a3sp_pd_suspend(void)
{
/*
* Serial consoles make use of SCIF hardware located in A3SP,
@@ -278,32 +136,22 @@ static int sh7372_a3sp_suspend(void)
return console_suspend_enabled ? 0 : -EBUSY;
}
-struct sh7372_pm_domain sh7372_a3sp = {
+struct rmobile_pm_domain sh7372_pd_a3sp = {
.genpd.name = "A3SP",
.bit_shift = 11,
.gov = &pm_domain_always_on_gov,
.no_debug = true,
- .suspend = sh7372_a3sp_suspend,
+ .suspend = sh7372_a3sp_pd_suspend,
};
-struct sh7372_pm_domain sh7372_a3sg = {
+struct rmobile_pm_domain sh7372_pd_a3sg = {
.genpd.name = "A3SG",
.bit_shift = 13,
};
-#else /* !CONFIG_PM */
-
-static inline void sh7372_a3sp_init(void) {}
-
-#endif /* !CONFIG_PM */
+#endif /* CONFIG_PM */
#if defined(CONFIG_SUSPEND) || defined(CONFIG_CPU_IDLE)
-static int sh7372_do_idle_core_standby(unsigned long unused)
-{
- cpu_do_idle(); /* WFI when SYSTBCR == 0x10 -> Core Standby */
- return 0;
-}
-
static void sh7372_set_reset_vector(unsigned long address)
{
/* set reset vector, translate 4k */
@@ -311,21 +159,6 @@ static void sh7372_set_reset_vector(unsigned long address)
__raw_writel(0, APARMBAREA);
}
-static void sh7372_enter_core_standby(void)
-{
- sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc));
-
- /* enter sleep mode with SYSTBCR to 0x10 */
- __raw_writel(0x10, SYSTBCR);
- cpu_suspend(0, sh7372_do_idle_core_standby);
- __raw_writel(0, SYSTBCR);
-
- /* disable reset vector translation */
- __raw_writel(0, SBAR);
-}
-#endif
-
-#ifdef CONFIG_SUSPEND
static void sh7372_enter_sysc(int pllc0_on, unsigned long sleep_mode)
{
if (pllc0_on)
@@ -465,22 +298,42 @@ static void sh7372_setup_sysc(unsigned long msk, unsigned long msk2)
static void sh7372_enter_a3sm_common(int pllc0_on)
{
+ /* use INTCA together with SYSC for wakeup */
+ sh7372_setup_sysc(1 << 0, 0);
sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc));
sh7372_enter_sysc(pllc0_on, 1 << 12);
}
+#endif /* CONFIG_SUSPEND || CONFIG_CPU_IDLE */
-static void sh7372_enter_a4s_common(int pllc0_on)
+#ifdef CONFIG_CPU_IDLE
+static int sh7372_do_idle_core_standby(unsigned long unused)
{
- sh7372_intca_suspend();
- memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100);
- sh7372_set_reset_vector(SMFRAM);
- sh7372_enter_sysc(pllc0_on, 1 << 10);
- sh7372_intca_resume();
+ cpu_do_idle(); /* WFI when SYSTBCR == 0x10 -> Core Standby */
+ return 0;
}
-#endif
+static void sh7372_enter_core_standby(void)
+{
+ sh7372_set_reset_vector(__pa(sh7372_resume_core_standby_sysc));
-#ifdef CONFIG_CPU_IDLE
+ /* enter sleep mode with SYSTBCR to 0x10 */
+ __raw_writel(0x10, SYSTBCR);
+ cpu_suspend(0, sh7372_do_idle_core_standby);
+ __raw_writel(0, SYSTBCR);
+
+ /* disable reset vector translation */
+ __raw_writel(0, SBAR);
+}
+
+static void sh7372_enter_a3sm_pll_on(void)
+{
+ sh7372_enter_a3sm_common(1);
+}
+
+static void sh7372_enter_a3sm_pll_off(void)
+{
+ sh7372_enter_a3sm_common(0);
+}
static void sh7372_cpuidle_setup(struct cpuidle_driver *drv)
{
@@ -492,7 +345,24 @@ static void sh7372_cpuidle_setup(struct cpuidle_driver *drv)
state->target_residency = 20 + 10;
state->flags = CPUIDLE_FLAG_TIME_VALID;
shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_core_standby;
+ drv->state_count++;
+
+ state = &drv->states[drv->state_count];
+ snprintf(state->name, CPUIDLE_NAME_LEN, "C3");
+ strncpy(state->desc, "A3SM PLL ON", CPUIDLE_DESC_LEN);
+ state->exit_latency = 20;
+ state->target_residency = 30 + 20;
+ state->flags = CPUIDLE_FLAG_TIME_VALID;
+ shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_a3sm_pll_on;
+ drv->state_count++;
+ state = &drv->states[drv->state_count];
+ snprintf(state->name, CPUIDLE_NAME_LEN, "C4");
+ strncpy(state->desc, "A3SM PLL OFF", CPUIDLE_DESC_LEN);
+ state->exit_latency = 120;
+ state->target_residency = 30 + 120;
+ state->flags = CPUIDLE_FLAG_TIME_VALID;
+ shmobile_cpuidle_modes[drv->state_count] = sh7372_enter_a3sm_pll_off;
drv->state_count++;
}
@@ -505,6 +375,14 @@ static void sh7372_cpuidle_init(void) {}
#endif
#ifdef CONFIG_SUSPEND
+static void sh7372_enter_a4s_common(int pllc0_on)
+{
+ sh7372_intca_suspend();
+ memcpy((void *)SMFRAM, sh7372_resume_core_standby_sysc, 0x100);
+ sh7372_set_reset_vector(SMFRAM);
+ sh7372_enter_sysc(pllc0_on, 1 << 10);
+ sh7372_intca_resume();
+}
static int sh7372_enter_suspend(suspend_state_t suspend_state)
{
@@ -512,24 +390,21 @@ static int sh7372_enter_suspend(suspend_state_t suspend_state)
/* check active clocks to determine potential wakeup sources */
if (sh7372_sysc_valid(&msk, &msk2)) {
- /* convert INTC mask and sense to SYSC mask and sense */
- sh7372_setup_sysc(msk, msk2);
-
if (!console_suspend_enabled &&
- sh7372_a4s.genpd.status == GPD_STATE_POWER_OFF) {
+ sh7372_pd_a4s.genpd.status == GPD_STATE_POWER_OFF) {
+ /* convert INTC mask/sense to SYSC mask/sense */
+ sh7372_setup_sysc(msk, msk2);
+
/* enter A4S sleep with PLLC0 off */
pr_debug("entering A4S\n");
sh7372_enter_a4s_common(0);
- } else {
- /* enter A3SM sleep with PLLC0 off */
- pr_debug("entering A3SM\n");
- sh7372_enter_a3sm_common(0);
+ return 0;
}
- } else {
- /* default to Core Standby that supports all wakeup sources */
- pr_debug("entering Core Standby\n");
- sh7372_enter_core_standby();
}
+
+ /* default to enter A3SM sleep with PLLC0 off */
+ pr_debug("entering A3SM\n");
+ sh7372_enter_a3sm_common(0);
return 0;
}
@@ -550,7 +425,7 @@ static int sh7372_pm_notifier_fn(struct notifier_block *notifier,
* executed during system suspend and resume, respectively, so
* that those functions don't crash while accessing the INTCS.
*/
- pm_genpd_poweron(&sh7372_a4r.genpd);
+ pm_genpd_poweron(&sh7372_pd_a4r.genpd);
break;
case PM_POST_SUSPEND:
pm_genpd_poweroff_unused();
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index ec4eb49c169..78948a9dba0 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -23,9 +23,14 @@
#include <linux/init.h>
#include <linux/io.h>
#include <linux/platform_device.h>
+#include <linux/of_platform.h>
#include <linux/serial_sci.h>
+#include <linux/sh_dma.h>
#include <linux/sh_timer.h>
+#include <linux/dma-mapping.h>
+#include <mach/dma-register.h>
#include <mach/r8a7740.h>
+#include <mach/pm-rmobile.h>
#include <mach/common.h>
#include <mach/irqs.h>
#include <asm/mach-types.h>
@@ -276,6 +281,272 @@ static struct platform_device *r8a7740_early_devices[] __initdata = {
&cmt10_device,
};
+/* DMA */
+static const struct sh_dmae_slave_config r8a7740_dmae_slaves[] = {
+ {
+ .slave_id = SHDMA_SLAVE_SDHI0_TX,
+ .addr = 0xe6850030,
+ .chcr = CHCR_TX(XMIT_SZ_16BIT),
+ .mid_rid = 0xc1,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI0_RX,
+ .addr = 0xe6850030,
+ .chcr = CHCR_RX(XMIT_SZ_16BIT),
+ .mid_rid = 0xc2,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI1_TX,
+ .addr = 0xe6860030,
+ .chcr = CHCR_TX(XMIT_SZ_16BIT),
+ .mid_rid = 0xc9,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI1_RX,
+ .addr = 0xe6860030,
+ .chcr = CHCR_RX(XMIT_SZ_16BIT),
+ .mid_rid = 0xca,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI2_TX,
+ .addr = 0xe6870030,
+ .chcr = CHCR_TX(XMIT_SZ_16BIT),
+ .mid_rid = 0xcd,
+ }, {
+ .slave_id = SHDMA_SLAVE_SDHI2_RX,
+ .addr = 0xe6870030,
+ .chcr = CHCR_RX(XMIT_SZ_16BIT),
+ .mid_rid = 0xce,
+ }, {
+ .slave_id = SHDMA_SLAVE_FSIA_TX,
+ .addr = 0xfe1f0024,
+ .chcr = CHCR_TX(XMIT_SZ_32BIT),
+ .mid_rid = 0xb1,
+ }, {
+ .slave_id = SHDMA_SLAVE_FSIA_RX,
+ .addr = 0xfe1f0020,
+ .chcr = CHCR_RX(XMIT_SZ_32BIT),
+ .mid_rid = 0xb2,
+ }, {
+ .slave_id = SHDMA_SLAVE_FSIB_TX,
+ .addr = 0xfe1f0064,
+ .chcr = CHCR_TX(XMIT_SZ_32BIT),
+ .mid_rid = 0xb5,
+ },
+};
+
+#define DMA_CHANNEL(a, b, c) \
+{ \
+ .offset = a, \
+ .dmars = b, \
+ .dmars_bit = c, \
+ .chclr_offset = (0x220 - 0x20) + a \
+}
+
+static const struct sh_dmae_channel r8a7740_dmae_channels[] = {
+ DMA_CHANNEL(0x00, 0, 0),
+ DMA_CHANNEL(0x10, 0, 8),
+ DMA_CHANNEL(0x20, 4, 0),
+ DMA_CHANNEL(0x30, 4, 8),
+ DMA_CHANNEL(0x50, 8, 0),
+ DMA_CHANNEL(0x60, 8, 8),
+};
+
+static struct sh_dmae_pdata dma_platform_data = {
+ .slave = r8a7740_dmae_slaves,
+ .slave_num = ARRAY_SIZE(r8a7740_dmae_slaves),
+ .channel = r8a7740_dmae_channels,
+ .channel_num = ARRAY_SIZE(r8a7740_dmae_channels),
+ .ts_low_shift = TS_LOW_SHIFT,
+ .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT,
+ .ts_high_shift = TS_HI_SHIFT,
+ .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT,
+ .ts_shift = dma_ts_shift,
+ .ts_shift_num = ARRAY_SIZE(dma_ts_shift),
+ .dmaor_init = DMAOR_DME,
+ .chclr_present = 1,
+};
+
+/* Resource order important! */
+static struct resource r8a7740_dmae0_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xfe008020,
+ .end = 0xfe00828f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMARSx */
+ .start = 0xfe009000,
+ .end = 0xfe00900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "error_irq",
+ .start = evt2irq(0x20c0),
+ .end = evt2irq(0x20c0),
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-5 */
+ .start = evt2irq(0x2000),
+ .end = evt2irq(0x20a0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* Resource order important! */
+static struct resource r8a7740_dmae1_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xfe018020,
+ .end = 0xfe01828f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMARSx */
+ .start = 0xfe019000,
+ .end = 0xfe01900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "error_irq",
+ .start = evt2irq(0x21c0),
+ .end = evt2irq(0x21c0),
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-5 */
+ .start = evt2irq(0x2100),
+ .end = evt2irq(0x21a0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+/* Resource order important! */
+static struct resource r8a7740_dmae2_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xfe028020,
+ .end = 0xfe02828f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMARSx */
+ .start = 0xfe029000,
+ .end = 0xfe02900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "error_irq",
+ .start = evt2irq(0x22c0),
+ .end = evt2irq(0x22c0),
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-5 */
+ .start = evt2irq(0x2200),
+ .end = evt2irq(0x22a0),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device dma0_device = {
+ .name = "sh-dma-engine",
+ .id = 0,
+ .resource = r8a7740_dmae0_resources,
+ .num_resources = ARRAY_SIZE(r8a7740_dmae0_resources),
+ .dev = {
+ .platform_data = &dma_platform_data,
+ },
+};
+
+static struct platform_device dma1_device = {
+ .name = "sh-dma-engine",
+ .id = 1,
+ .resource = r8a7740_dmae1_resources,
+ .num_resources = ARRAY_SIZE(r8a7740_dmae1_resources),
+ .dev = {
+ .platform_data = &dma_platform_data,
+ },
+};
+
+static struct platform_device dma2_device = {
+ .name = "sh-dma-engine",
+ .id = 2,
+ .resource = r8a7740_dmae2_resources,
+ .num_resources = ARRAY_SIZE(r8a7740_dmae2_resources),
+ .dev = {
+ .platform_data = &dma_platform_data,
+ },
+};
+
+/* USB-DMAC */
+static const struct sh_dmae_channel r8a7740_usb_dma_channels[] = {
+ {
+ .offset = 0,
+ }, {
+ .offset = 0x20,
+ },
+};
+
+static const struct sh_dmae_slave_config r8a7740_usb_dma_slaves[] = {
+ {
+ .slave_id = SHDMA_SLAVE_USBHS_TX,
+ .chcr = USBTS_INDEX2VAL(USBTS_XMIT_SZ_8BYTE),
+ }, {
+ .slave_id = SHDMA_SLAVE_USBHS_RX,
+ .chcr = USBTS_INDEX2VAL(USBTS_XMIT_SZ_8BYTE),
+ },
+};
+
+static struct sh_dmae_pdata usb_dma_platform_data = {
+ .slave = r8a7740_usb_dma_slaves,
+ .slave_num = ARRAY_SIZE(r8a7740_usb_dma_slaves),
+ .channel = r8a7740_usb_dma_channels,
+ .channel_num = ARRAY_SIZE(r8a7740_usb_dma_channels),
+ .ts_low_shift = USBTS_LOW_SHIFT,
+ .ts_low_mask = USBTS_LOW_BIT << USBTS_LOW_SHIFT,
+ .ts_high_shift = USBTS_HI_SHIFT,
+ .ts_high_mask = USBTS_HI_BIT << USBTS_HI_SHIFT,
+ .ts_shift = dma_usbts_shift,
+ .ts_shift_num = ARRAY_SIZE(dma_usbts_shift),
+ .dmaor_init = DMAOR_DME,
+ .chcr_offset = 0x14,
+ .chcr_ie_bit = 1 << 5,
+ .dmaor_is_32bit = 1,
+ .needs_tend_set = 1,
+ .no_dmars = 1,
+ .slave_only = 1,
+};
+
+static struct resource r8a7740_usb_dma_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xe68a0020,
+ .end = 0xe68a0064 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* VCR/SWR/DMICR */
+ .start = 0xe68a0000,
+ .end = 0xe68a0014 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* IRQ for channels */
+ .start = evt2irq(0x0a00),
+ .end = evt2irq(0x0a00),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device usb_dma_device = {
+ .name = "sh-dma-engine",
+ .id = 3,
+ .resource = r8a7740_usb_dma_resources,
+ .num_resources = ARRAY_SIZE(r8a7740_usb_dma_resources),
+ .dev = {
+ .platform_data = &usb_dma_platform_data,
+ },
+};
+
/* I2C */
static struct resource i2c0_resources[] = {
[0] = {
@@ -322,8 +593,30 @@ static struct platform_device i2c1_device = {
static struct platform_device *r8a7740_late_devices[] __initdata = {
&i2c0_device,
&i2c1_device,
+ &dma0_device,
+ &dma1_device,
+ &dma2_device,
+ &usb_dma_device,
};
+/*
+ * r8a7740 chip has lasting errata on MERAM buffer.
+ * this is work-around for it.
+ * see
+ * "Media RAM (MERAM)" on r8a7740 documentation
+ */
+#define MEBUFCNTR 0xFE950098
+void r8a7740_meram_workaround(void)
+{
+ void __iomem *reg;
+
+ reg = ioremap_nocache(MEBUFCNTR, 4);
+ if (reg) {
+ iowrite32(0x01600164, reg);
+ iounmap(reg);
+ }
+}
+
#define ICCR 0x0004
#define ICSTART 0x0070
@@ -380,10 +673,31 @@ void __init r8a7740_add_standard_devices(void)
r8a7740_i2c_workaround(&i2c0_device);
r8a7740_i2c_workaround(&i2c1_device);
+ /* PM domain */
+ rmobile_init_pm_domain(&r8a7740_pd_a4s);
+ rmobile_init_pm_domain(&r8a7740_pd_a3sp);
+ rmobile_init_pm_domain(&r8a7740_pd_a4lc);
+
+ rmobile_pm_add_subdomain(&r8a7740_pd_a4s, &r8a7740_pd_a3sp);
+
+ /* add devices */
platform_add_devices(r8a7740_early_devices,
ARRAY_SIZE(r8a7740_early_devices));
platform_add_devices(r8a7740_late_devices,
ARRAY_SIZE(r8a7740_late_devices));
+
+ /* add devices to PM domain */
+
+ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif0_device);
+ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif1_device);
+ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif2_device);
+ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif3_device);
+ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif4_device);
+ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif5_device);
+ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif6_device);
+ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scif7_device);
+ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &scifb_device);
+ rmobile_add_device_to_domain(&r8a7740_pd_a3sp, &i2c1_device);
}
static void __init r8a7740_earlytimer_init(void)
@@ -403,3 +717,49 @@ void __init r8a7740_add_early_devices(void)
/* override timer setup with soc-specific code */
shmobile_timer.init = r8a7740_earlytimer_init;
}
+
+#ifdef CONFIG_USE_OF
+
+void __init r8a7740_add_early_devices_dt(void)
+{
+ shmobile_setup_delay(800, 1, 3); /* Cortex-A9 @ 800MHz */
+
+ early_platform_add_devices(r8a7740_early_devices,
+ ARRAY_SIZE(r8a7740_early_devices));
+
+ /* setup early console here as well */
+ shmobile_setup_console();
+}
+
+static const struct of_dev_auxdata r8a7740_auxdata_lookup[] __initconst = {
+ { }
+};
+
+void __init r8a7740_add_standard_devices_dt(void)
+{
+ /* clocks are setup late during boot in the case of DT */
+ r8a7740_clock_init(0);
+
+ platform_add_devices(r8a7740_early_devices,
+ ARRAY_SIZE(r8a7740_early_devices));
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ r8a7740_auxdata_lookup, NULL);
+}
+
+static const char *r8a7740_boards_compat_dt[] __initdata = {
+ "renesas,r8a7740",
+ NULL,
+};
+
+DT_MACHINE_START(SH7372_DT, "Generic R8A7740 (Flattened Device Tree)")
+ .map_io = r8a7740_map_io,
+ .init_early = r8a7740_add_early_devices_dt,
+ .init_irq = r8a7740_init_irq,
+ .handle_irq = shmobile_handle_irq_intc,
+ .init_machine = r8a7740_add_standard_devices_dt,
+ .timer = &shmobile_timer,
+ .dt_compat = r8a7740_boards_compat_dt,
+MACHINE_END
+
+#endif /* CONFIG_USE_OF */
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c
index fafce9ce821..838a87be1d5 100644
--- a/arch/arm/mach-shmobile/setup-sh7372.c
+++ b/arch/arm/mach-shmobile/setup-sh7372.c
@@ -33,6 +33,7 @@
#include <linux/sh_timer.h>
#include <linux/pm_domain.h>
#include <linux/dma-mapping.h>
+#include <mach/dma-register.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
#include <mach/sh7372.h>
@@ -335,151 +336,126 @@ static struct platform_device iic1_device = {
};
/* DMA */
-/* Transmit sizes and respective CHCR register values */
-enum {
- XMIT_SZ_8BIT = 0,
- XMIT_SZ_16BIT = 1,
- XMIT_SZ_32BIT = 2,
- XMIT_SZ_64BIT = 7,
- XMIT_SZ_128BIT = 3,
- XMIT_SZ_256BIT = 4,
- XMIT_SZ_512BIT = 5,
-};
-
-/* log2(size / 8) - used to calculate number of transfers */
-#define TS_SHIFT { \
- [XMIT_SZ_8BIT] = 0, \
- [XMIT_SZ_16BIT] = 1, \
- [XMIT_SZ_32BIT] = 2, \
- [XMIT_SZ_64BIT] = 3, \
- [XMIT_SZ_128BIT] = 4, \
- [XMIT_SZ_256BIT] = 5, \
- [XMIT_SZ_512BIT] = 6, \
-}
-
-#define TS_INDEX2VAL(i) ((((i) & 3) << 3) | \
- (((i) & 0xc) << (20 - 2)))
-
static const struct sh_dmae_slave_config sh7372_dmae_slaves[] = {
{
.slave_id = SHDMA_SLAVE_SCIF0_TX,
.addr = 0xe6c40020,
- .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .chcr = CHCR_TX(XMIT_SZ_8BIT),
.mid_rid = 0x21,
}, {
.slave_id = SHDMA_SLAVE_SCIF0_RX,
.addr = 0xe6c40024,
- .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .chcr = CHCR_RX(XMIT_SZ_8BIT),
.mid_rid = 0x22,
}, {
.slave_id = SHDMA_SLAVE_SCIF1_TX,
.addr = 0xe6c50020,
- .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .chcr = CHCR_TX(XMIT_SZ_8BIT),
.mid_rid = 0x25,
}, {
.slave_id = SHDMA_SLAVE_SCIF1_RX,
.addr = 0xe6c50024,
- .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .chcr = CHCR_RX(XMIT_SZ_8BIT),
.mid_rid = 0x26,
}, {
.slave_id = SHDMA_SLAVE_SCIF2_TX,
.addr = 0xe6c60020,
- .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .chcr = CHCR_TX(XMIT_SZ_8BIT),
.mid_rid = 0x29,
}, {
.slave_id = SHDMA_SLAVE_SCIF2_RX,
.addr = 0xe6c60024,
- .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .chcr = CHCR_RX(XMIT_SZ_8BIT),
.mid_rid = 0x2a,
}, {
.slave_id = SHDMA_SLAVE_SCIF3_TX,
.addr = 0xe6c70020,
- .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .chcr = CHCR_TX(XMIT_SZ_8BIT),
.mid_rid = 0x2d,
}, {
.slave_id = SHDMA_SLAVE_SCIF3_RX,
.addr = 0xe6c70024,
- .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .chcr = CHCR_RX(XMIT_SZ_8BIT),
.mid_rid = 0x2e,
}, {
.slave_id = SHDMA_SLAVE_SCIF4_TX,
.addr = 0xe6c80020,
- .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .chcr = CHCR_TX(XMIT_SZ_8BIT),
.mid_rid = 0x39,
}, {
.slave_id = SHDMA_SLAVE_SCIF4_RX,
.addr = 0xe6c80024,
- .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .chcr = CHCR_RX(XMIT_SZ_8BIT),
.mid_rid = 0x3a,
}, {
.slave_id = SHDMA_SLAVE_SCIF5_TX,
.addr = 0xe6cb0020,
- .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .chcr = CHCR_TX(XMIT_SZ_8BIT),
.mid_rid = 0x35,
}, {
.slave_id = SHDMA_SLAVE_SCIF5_RX,
.addr = 0xe6cb0024,
- .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .chcr = CHCR_RX(XMIT_SZ_8BIT),
.mid_rid = 0x36,
}, {
.slave_id = SHDMA_SLAVE_SCIF6_TX,
.addr = 0xe6c30040,
- .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .chcr = CHCR_TX(XMIT_SZ_8BIT),
.mid_rid = 0x3d,
}, {
.slave_id = SHDMA_SLAVE_SCIF6_RX,
.addr = 0xe6c30060,
- .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_8BIT),
+ .chcr = CHCR_RX(XMIT_SZ_8BIT),
.mid_rid = 0x3e,
}, {
.slave_id = SHDMA_SLAVE_SDHI0_TX,
.addr = 0xe6850030,
- .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
+ .chcr = CHCR_TX(XMIT_SZ_16BIT),
.mid_rid = 0xc1,
}, {
.slave_id = SHDMA_SLAVE_SDHI0_RX,
.addr = 0xe6850030,
- .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
+ .chcr = CHCR_RX(XMIT_SZ_16BIT),
.mid_rid = 0xc2,
}, {
.slave_id = SHDMA_SLAVE_SDHI1_TX,
.addr = 0xe6860030,
- .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
+ .chcr = CHCR_TX(XMIT_SZ_16BIT),
.mid_rid = 0xc9,
}, {
.slave_id = SHDMA_SLAVE_SDHI1_RX,
.addr = 0xe6860030,
- .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
+ .chcr = CHCR_RX(XMIT_SZ_16BIT),
.mid_rid = 0xca,
}, {
.slave_id = SHDMA_SLAVE_SDHI2_TX,
.addr = 0xe6870030,
- .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
+ .chcr = CHCR_TX(XMIT_SZ_16BIT),
.mid_rid = 0xcd,
}, {
.slave_id = SHDMA_SLAVE_SDHI2_RX,
.addr = 0xe6870030,
- .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_16BIT),
+ .chcr = CHCR_RX(XMIT_SZ_16BIT),
.mid_rid = 0xce,
}, {
.slave_id = SHDMA_SLAVE_FSIA_TX,
.addr = 0xfe1f0024,
- .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+ .chcr = CHCR_TX(XMIT_SZ_32BIT),
.mid_rid = 0xb1,
}, {
.slave_id = SHDMA_SLAVE_FSIA_RX,
.addr = 0xfe1f0020,
- .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+ .chcr = CHCR_RX(XMIT_SZ_32BIT),
.mid_rid = 0xb2,
}, {
.slave_id = SHDMA_SLAVE_MMCIF_TX,
.addr = 0xe6bd0034,
- .chcr = DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+ .chcr = CHCR_TX(XMIT_SZ_32BIT),
.mid_rid = 0xd1,
}, {
.slave_id = SHDMA_SLAVE_MMCIF_RX,
.addr = 0xe6bd0034,
- .chcr = DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL(XMIT_SZ_32BIT),
+ .chcr = CHCR_RX(XMIT_SZ_32BIT),
.mid_rid = 0xd2,
},
};
@@ -520,19 +496,17 @@ static const struct sh_dmae_channel sh7372_dmae_channels[] = {
}
};
-static const unsigned int ts_shift[] = TS_SHIFT;
-
static struct sh_dmae_pdata dma_platform_data = {
.slave = sh7372_dmae_slaves,
.slave_num = ARRAY_SIZE(sh7372_dmae_slaves),
.channel = sh7372_dmae_channels,
.channel_num = ARRAY_SIZE(sh7372_dmae_channels),
- .ts_low_shift = 3,
- .ts_low_mask = 0x18,
- .ts_high_shift = (20 - 2), /* 2 bits for shifted low TS */
- .ts_high_mask = 0x00300000,
- .ts_shift = ts_shift,
- .ts_shift_num = ARRAY_SIZE(ts_shift),
+ .ts_low_shift = TS_LOW_SHIFT,
+ .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT,
+ .ts_high_shift = TS_HI_SHIFT,
+ .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT,
+ .ts_shift = dma_ts_shift,
+ .ts_shift_num = ARRAY_SIZE(dma_ts_shift),
.dmaor_init = DMAOR_DME,
.chclr_present = 1,
};
@@ -654,17 +628,6 @@ static struct platform_device dma2_device = {
/*
* USB-DMAC
*/
-
-unsigned int usbts_shift[] = {3, 4, 5};
-
-enum {
- XMIT_SZ_8BYTE = 0,
- XMIT_SZ_16BYTE = 1,
- XMIT_SZ_32BYTE = 2,
-};
-
-#define USBTS_INDEX2VAL(i) (((i) & 3) << 6)
-
static const struct sh_dmae_channel sh7372_usb_dmae_channels[] = {
{
.offset = 0,
@@ -677,10 +640,10 @@ static const struct sh_dmae_channel sh7372_usb_dmae_channels[] = {
static const struct sh_dmae_slave_config sh7372_usb_dmae0_slaves[] = {
{
.slave_id = SHDMA_SLAVE_USB0_TX,
- .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE),
+ .chcr = USBTS_INDEX2VAL(USBTS_XMIT_SZ_8BYTE),
}, {
.slave_id = SHDMA_SLAVE_USB0_RX,
- .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE),
+ .chcr = USBTS_INDEX2VAL(USBTS_XMIT_SZ_8BYTE),
},
};
@@ -689,12 +652,12 @@ static struct sh_dmae_pdata usb_dma0_platform_data = {
.slave_num = ARRAY_SIZE(sh7372_usb_dmae0_slaves),
.channel = sh7372_usb_dmae_channels,
.channel_num = ARRAY_SIZE(sh7372_usb_dmae_channels),
- .ts_low_shift = 6,
- .ts_low_mask = 0xc0,
- .ts_high_shift = 0,
- .ts_high_mask = 0,
- .ts_shift = usbts_shift,
- .ts_shift_num = ARRAY_SIZE(usbts_shift),
+ .ts_low_shift = USBTS_LOW_SHIFT,
+ .ts_low_mask = USBTS_LOW_BIT << USBTS_LOW_SHIFT,
+ .ts_high_shift = USBTS_HI_SHIFT,
+ .ts_high_mask = USBTS_HI_BIT << USBTS_HI_SHIFT,
+ .ts_shift = dma_usbts_shift,
+ .ts_shift_num = ARRAY_SIZE(dma_usbts_shift),
.dmaor_init = DMAOR_DME,
.chcr_offset = 0x14,
.chcr_ie_bit = 1 << 5,
@@ -739,10 +702,10 @@ static struct platform_device usb_dma0_device = {
static const struct sh_dmae_slave_config sh7372_usb_dmae1_slaves[] = {
{
.slave_id = SHDMA_SLAVE_USB1_TX,
- .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE),
+ .chcr = USBTS_INDEX2VAL(USBTS_XMIT_SZ_8BYTE),
}, {
.slave_id = SHDMA_SLAVE_USB1_RX,
- .chcr = USBTS_INDEX2VAL(XMIT_SZ_8BYTE),
+ .chcr = USBTS_INDEX2VAL(USBTS_XMIT_SZ_8BYTE),
},
};
@@ -751,12 +714,12 @@ static struct sh_dmae_pdata usb_dma1_platform_data = {
.slave_num = ARRAY_SIZE(sh7372_usb_dmae1_slaves),
.channel = sh7372_usb_dmae_channels,
.channel_num = ARRAY_SIZE(sh7372_usb_dmae_channels),
- .ts_low_shift = 6,
- .ts_low_mask = 0xc0,
- .ts_high_shift = 0,
- .ts_high_mask = 0,
- .ts_shift = usbts_shift,
- .ts_shift_num = ARRAY_SIZE(usbts_shift),
+ .ts_low_shift = USBTS_LOW_SHIFT,
+ .ts_low_mask = USBTS_LOW_BIT << USBTS_LOW_SHIFT,
+ .ts_high_shift = USBTS_HI_SHIFT,
+ .ts_high_mask = USBTS_HI_BIT << USBTS_HI_SHIFT,
+ .ts_shift = dma_usbts_shift,
+ .ts_shift_num = ARRAY_SIZE(dma_usbts_shift),
.dmaor_init = DMAOR_DME,
.chcr_offset = 0x14,
.chcr_ie_bit = 1 << 5,
@@ -1038,21 +1001,21 @@ static struct platform_device *sh7372_late_devices[] __initdata = {
void __init sh7372_add_standard_devices(void)
{
- sh7372_init_pm_domain(&sh7372_a4lc);
- sh7372_init_pm_domain(&sh7372_a4mp);
- sh7372_init_pm_domain(&sh7372_d4);
- sh7372_init_pm_domain(&sh7372_a4r);
- sh7372_init_pm_domain(&sh7372_a3rv);
- sh7372_init_pm_domain(&sh7372_a3ri);
- sh7372_init_pm_domain(&sh7372_a4s);
- sh7372_init_pm_domain(&sh7372_a3sp);
- sh7372_init_pm_domain(&sh7372_a3sg);
-
- sh7372_pm_add_subdomain(&sh7372_a4lc, &sh7372_a3rv);
- sh7372_pm_add_subdomain(&sh7372_a4r, &sh7372_a4lc);
-
- sh7372_pm_add_subdomain(&sh7372_a4s, &sh7372_a3sg);
- sh7372_pm_add_subdomain(&sh7372_a4s, &sh7372_a3sp);
+ rmobile_init_pm_domain(&sh7372_pd_a4lc);
+ rmobile_init_pm_domain(&sh7372_pd_a4mp);
+ rmobile_init_pm_domain(&sh7372_pd_d4);
+ rmobile_init_pm_domain(&sh7372_pd_a4r);
+ rmobile_init_pm_domain(&sh7372_pd_a3rv);
+ rmobile_init_pm_domain(&sh7372_pd_a3ri);
+ rmobile_init_pm_domain(&sh7372_pd_a4s);
+ rmobile_init_pm_domain(&sh7372_pd_a3sp);
+ rmobile_init_pm_domain(&sh7372_pd_a3sg);
+
+ rmobile_pm_add_subdomain(&sh7372_pd_a4lc, &sh7372_pd_a3rv);
+ rmobile_pm_add_subdomain(&sh7372_pd_a4r, &sh7372_pd_a4lc);
+
+ rmobile_pm_add_subdomain(&sh7372_pd_a4s, &sh7372_pd_a3sg);
+ rmobile_pm_add_subdomain(&sh7372_pd_a4s, &sh7372_pd_a3sp);
platform_add_devices(sh7372_early_devices,
ARRAY_SIZE(sh7372_early_devices));
@@ -1060,30 +1023,30 @@ void __init sh7372_add_standard_devices(void)
platform_add_devices(sh7372_late_devices,
ARRAY_SIZE(sh7372_late_devices));
- sh7372_add_device_to_domain(&sh7372_a3rv, &vpu_device);
- sh7372_add_device_to_domain(&sh7372_a4mp, &spu0_device);
- sh7372_add_device_to_domain(&sh7372_a4mp, &spu1_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &scif0_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &scif1_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &scif2_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &scif3_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &scif4_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &scif5_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &scif6_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &iic1_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &dma0_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &dma1_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &dma2_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &usb_dma0_device);
- sh7372_add_device_to_domain(&sh7372_a3sp, &usb_dma1_device);
- sh7372_add_device_to_domain(&sh7372_a4r, &iic0_device);
- sh7372_add_device_to_domain(&sh7372_a4r, &veu0_device);
- sh7372_add_device_to_domain(&sh7372_a4r, &veu1_device);
- sh7372_add_device_to_domain(&sh7372_a4r, &veu2_device);
- sh7372_add_device_to_domain(&sh7372_a4r, &veu3_device);
- sh7372_add_device_to_domain(&sh7372_a4r, &jpu_device);
- sh7372_add_device_to_domain(&sh7372_a4r, &tmu00_device);
- sh7372_add_device_to_domain(&sh7372_a4r, &tmu01_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3rv, &vpu_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4mp, &spu0_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4mp, &spu1_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif0_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif1_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif2_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif3_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif4_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif5_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &scif6_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &iic1_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &dma0_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &dma1_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &dma2_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usb_dma0_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a3sp, &usb_dma1_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4r, &iic0_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu0_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu1_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu2_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4r, &veu3_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4r, &jpu_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4r, &tmu00_device);
+ rmobile_add_device_to_domain(&sh7372_pd_a4r, &tmu01_device);
}
static void __init sh7372_earlytimer_init(void)
diff --git a/arch/arm/mach-shmobile/setup-sh7377.c b/arch/arm/mach-shmobile/setup-sh7377.c
index d576a6abbad..855b1506caf 100644
--- a/arch/arm/mach-shmobile/setup-sh7377.c
+++ b/arch/arm/mach-shmobile/setup-sh7377.c
@@ -22,6 +22,7 @@
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/platform_device.h>
+#include <linux/of_platform.h>
#include <linux/uio_driver.h>
#include <linux/delay.h>
#include <linux/input.h>
@@ -500,3 +501,49 @@ void __init sh7377_add_early_devices(void)
/* override timer setup with soc-specific code */
shmobile_timer.init = sh7377_earlytimer_init;
}
+
+#ifdef CONFIG_USE_OF
+
+void __init sh7377_add_early_devices_dt(void)
+{
+ shmobile_setup_delay(600, 1, 3); /* Cortex-A8 @ 600MHz */
+
+ early_platform_add_devices(sh7377_early_devices,
+ ARRAY_SIZE(sh7377_early_devices));
+
+ /* setup early console here as well */
+ shmobile_setup_console();
+}
+
+static const struct of_dev_auxdata sh7377_auxdata_lookup[] __initconst = {
+ { }
+};
+
+void __init sh7377_add_standard_devices_dt(void)
+{
+ /* clocks are setup late during boot in the case of DT */
+ sh7377_clock_init();
+
+ platform_add_devices(sh7377_early_devices,
+ ARRAY_SIZE(sh7377_early_devices));
+
+ of_platform_populate(NULL, of_default_bus_match_table,
+ sh7377_auxdata_lookup, NULL);
+}
+
+static const char *sh7377_boards_compat_dt[] __initdata = {
+ "renesas,sh7377",
+ NULL,
+};
+
+DT_MACHINE_START(SH7377_DT, "Generic SH7377 (Flattened Device Tree)")
+ .map_io = sh7377_map_io,
+ .init_early = sh7377_add_early_devices_dt,
+ .init_irq = sh7377_init_irq,
+ .handle_irq = shmobile_handle_irq_intc,
+ .init_machine = sh7377_add_standard_devices_dt,
+ .timer = &shmobile_timer,
+ .dt_compat = sh7377_boards_compat_dt,
+MACHINE_END
+
+#endif /* CONFIG_USE_OF */
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
index 04a0dfe7549..d230af656fc 100644
--- a/arch/arm/mach-shmobile/setup-sh73a0.c
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -30,6 +30,7 @@
#include <linux/sh_dma.h>
#include <linux/sh_intc.h>
#include <linux/sh_timer.h>
+#include <mach/dma-register.h>
#include <mach/hardware.h>
#include <mach/irqs.h>
#include <mach/sh73a0.h>
@@ -415,32 +416,6 @@ static struct platform_device i2c4_device = {
.num_resources = ARRAY_SIZE(i2c4_resources),
};
-/* Transmit sizes and respective CHCR register values */
-enum {
- XMIT_SZ_8BIT = 0,
- XMIT_SZ_16BIT = 1,
- XMIT_SZ_32BIT = 2,
- XMIT_SZ_64BIT = 7,
- XMIT_SZ_128BIT = 3,
- XMIT_SZ_256BIT = 4,
- XMIT_SZ_512BIT = 5,
-};
-
-/* log2(size / 8) - used to calculate number of transfers */
-#define TS_SHIFT { \
- [XMIT_SZ_8BIT] = 0, \
- [XMIT_SZ_16BIT] = 1, \
- [XMIT_SZ_32BIT] = 2, \
- [XMIT_SZ_64BIT] = 3, \
- [XMIT_SZ_128BIT] = 4, \
- [XMIT_SZ_256BIT] = 5, \
- [XMIT_SZ_512BIT] = 6, \
-}
-
-#define TS_INDEX2VAL(i) ((((i) & 3) << 3) | (((i) & 0xc) << (20 - 2)))
-#define CHCR_TX(xmit_sz) (DM_FIX | SM_INC | 0x800 | TS_INDEX2VAL((xmit_sz)))
-#define CHCR_RX(xmit_sz) (DM_INC | SM_FIX | 0x800 | TS_INDEX2VAL((xmit_sz)))
-
static const struct sh_dmae_slave_config sh73a0_dmae_slaves[] = {
{
.slave_id = SHDMA_SLAVE_SCIF0_TX,
@@ -604,19 +579,17 @@ static const struct sh_dmae_channel sh73a0_dmae_channels[] = {
DMAE_CHANNEL(0x8980),
};
-static const unsigned int ts_shift[] = TS_SHIFT;
-
static struct sh_dmae_pdata sh73a0_dmae_platform_data = {
.slave = sh73a0_dmae_slaves,
.slave_num = ARRAY_SIZE(sh73a0_dmae_slaves),
.channel = sh73a0_dmae_channels,
.channel_num = ARRAY_SIZE(sh73a0_dmae_channels),
- .ts_low_shift = 3,
- .ts_low_mask = 0x18,
- .ts_high_shift = (20 - 2), /* 2 bits for shifted low TS */
- .ts_high_mask = 0x00300000,
- .ts_shift = ts_shift,
- .ts_shift_num = ARRAY_SIZE(ts_shift),
+ .ts_low_shift = TS_LOW_SHIFT,
+ .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT,
+ .ts_high_shift = TS_HI_SHIFT,
+ .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT,
+ .ts_shift = dma_ts_shift,
+ .ts_shift_num = ARRAY_SIZE(dma_ts_shift),
.dmaor_init = DMAOR_DME,
};
@@ -651,6 +624,116 @@ static struct platform_device dma0_device = {
},
};
+/* MPDMAC */
+static const struct sh_dmae_slave_config sh73a0_mpdma_slaves[] = {
+ {
+ .slave_id = SHDMA_SLAVE_FSI2A_RX,
+ .addr = 0xec230020,
+ .chcr = CHCR_RX(XMIT_SZ_32BIT),
+ .mid_rid = 0xd6, /* CHECK ME */
+ }, {
+ .slave_id = SHDMA_SLAVE_FSI2A_TX,
+ .addr = 0xec230024,
+ .chcr = CHCR_TX(XMIT_SZ_32BIT),
+ .mid_rid = 0xd5, /* CHECK ME */
+ }, {
+ .slave_id = SHDMA_SLAVE_FSI2C_RX,
+ .addr = 0xec230060,
+ .chcr = CHCR_RX(XMIT_SZ_32BIT),
+ .mid_rid = 0xda, /* CHECK ME */
+ }, {
+ .slave_id = SHDMA_SLAVE_FSI2C_TX,
+ .addr = 0xec230064,
+ .chcr = CHCR_TX(XMIT_SZ_32BIT),
+ .mid_rid = 0xd9, /* CHECK ME */
+ }, {
+ .slave_id = SHDMA_SLAVE_FSI2B_RX,
+ .addr = 0xec240020,
+ .chcr = CHCR_RX(XMIT_SZ_32BIT),
+ .mid_rid = 0x8e, /* CHECK ME */
+ }, {
+ .slave_id = SHDMA_SLAVE_FSI2B_TX,
+ .addr = 0xec240024,
+ .chcr = CHCR_RX(XMIT_SZ_32BIT),
+ .mid_rid = 0x8d, /* CHECK ME */
+ }, {
+ .slave_id = SHDMA_SLAVE_FSI2D_RX,
+ .addr = 0xec240060,
+ .chcr = CHCR_RX(XMIT_SZ_32BIT),
+ .mid_rid = 0x9a, /* CHECK ME */
+ },
+};
+
+#define MPDMA_CHANNEL(a, b, c) \
+{ \
+ .offset = a, \
+ .dmars = b, \
+ .dmars_bit = c, \
+ .chclr_offset = (0x220 - 0x20) + a \
+}
+
+static const struct sh_dmae_channel sh73a0_mpdma_channels[] = {
+ MPDMA_CHANNEL(0x00, 0, 0),
+ MPDMA_CHANNEL(0x10, 0, 8),
+ MPDMA_CHANNEL(0x20, 4, 0),
+ MPDMA_CHANNEL(0x30, 4, 8),
+ MPDMA_CHANNEL(0x50, 8, 0),
+ MPDMA_CHANNEL(0x70, 8, 8),
+};
+
+static struct sh_dmae_pdata sh73a0_mpdma_platform_data = {
+ .slave = sh73a0_mpdma_slaves,
+ .slave_num = ARRAY_SIZE(sh73a0_mpdma_slaves),
+ .channel = sh73a0_mpdma_channels,
+ .channel_num = ARRAY_SIZE(sh73a0_mpdma_channels),
+ .ts_low_shift = TS_LOW_SHIFT,
+ .ts_low_mask = TS_LOW_BIT << TS_LOW_SHIFT,
+ .ts_high_shift = TS_HI_SHIFT,
+ .ts_high_mask = TS_HI_BIT << TS_HI_SHIFT,
+ .ts_shift = dma_ts_shift,
+ .ts_shift_num = ARRAY_SIZE(dma_ts_shift),
+ .dmaor_init = DMAOR_DME,
+ .chclr_present = 1,
+};
+
+/* Resource order important! */
+static struct resource sh73a0_mpdma_resources[] = {
+ {
+ /* Channel registers and DMAOR */
+ .start = 0xec618020,
+ .end = 0xec61828f,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ /* DMARSx */
+ .start = 0xec619000,
+ .end = 0xec61900b,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "error_irq",
+ .start = gic_spi(181),
+ .end = gic_spi(181),
+ .flags = IORESOURCE_IRQ,
+ },
+ {
+ /* IRQ for channels 0-5 */
+ .start = gic_spi(175),
+ .end = gic_spi(180),
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device mpdma0_device = {
+ .name = "sh-dma-engine",
+ .id = 1,
+ .resource = sh73a0_mpdma_resources,
+ .num_resources = ARRAY_SIZE(sh73a0_mpdma_resources),
+ .dev = {
+ .platform_data = &sh73a0_mpdma_platform_data,
+ },
+};
+
static struct platform_device *sh73a0_early_devices[] __initdata = {
&scif0_device,
&scif1_device,
@@ -673,6 +756,7 @@ static struct platform_device *sh73a0_late_devices[] __initdata = {
&i2c3_device,
&i2c4_device,
&dma0_device,
+ &mpdma0_device,
};
#define SRCR2 0xe61580b0
diff --git a/arch/arm/mach-spear3xx/spear300.c b/arch/arm/mach-spear3xx/spear300.c
index 0f882ecb7d8..6ec30054996 100644
--- a/arch/arm/mach-spear3xx/spear300.c
+++ b/arch/arm/mach-spear3xx/spear300.c
@@ -120,182 +120,156 @@ struct pl08x_channel_data spear300_dma_info[] = {
.min_signal = 2,
.max_signal = 2,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "uart0_tx",
.min_signal = 3,
.max_signal = 3,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ssp0_rx",
.min_signal = 8,
.max_signal = 8,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ssp0_tx",
.min_signal = 9,
.max_signal = 9,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "i2c_rx",
.min_signal = 10,
.max_signal = 10,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "i2c_tx",
.min_signal = 11,
.max_signal = 11,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "irda",
.min_signal = 12,
.max_signal = 12,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "adc",
.min_signal = 13,
.max_signal = 13,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "to_jpeg",
.min_signal = 14,
.max_signal = 14,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "from_jpeg",
.min_signal = 15,
.max_signal = 15,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras0_rx",
.min_signal = 0,
.max_signal = 0,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras0_tx",
.min_signal = 1,
.max_signal = 1,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras1_rx",
.min_signal = 2,
.max_signal = 2,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras1_tx",
.min_signal = 3,
.max_signal = 3,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras2_rx",
.min_signal = 4,
.max_signal = 4,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras2_tx",
.min_signal = 5,
.max_signal = 5,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras3_rx",
.min_signal = 6,
.max_signal = 6,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras3_tx",
.min_signal = 7,
.max_signal = 7,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras4_rx",
.min_signal = 8,
.max_signal = 8,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras4_tx",
.min_signal = 9,
.max_signal = 9,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras5_rx",
.min_signal = 10,
.max_signal = 10,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras5_tx",
.min_signal = 11,
.max_signal = 11,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras6_rx",
.min_signal = 12,
.max_signal = 12,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras6_tx",
.min_signal = 13,
.max_signal = 13,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras7_rx",
.min_signal = 14,
.max_signal = 14,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras7_tx",
.min_signal = 15,
.max_signal = 15,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
},
};
diff --git a/arch/arm/mach-spear3xx/spear310.c b/arch/arm/mach-spear3xx/spear310.c
index bbcf4571d36..1d0e435b904 100644
--- a/arch/arm/mach-spear3xx/spear310.c
+++ b/arch/arm/mach-spear3xx/spear310.c
@@ -205,182 +205,156 @@ struct pl08x_channel_data spear310_dma_info[] = {
.min_signal = 2,
.max_signal = 2,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "uart0_tx",
.min_signal = 3,
.max_signal = 3,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ssp0_rx",
.min_signal = 8,
.max_signal = 8,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ssp0_tx",
.min_signal = 9,
.max_signal = 9,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "i2c_rx",
.min_signal = 10,
.max_signal = 10,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "i2c_tx",
.min_signal = 11,
.max_signal = 11,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "irda",
.min_signal = 12,
.max_signal = 12,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "adc",
.min_signal = 13,
.max_signal = 13,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "to_jpeg",
.min_signal = 14,
.max_signal = 14,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "from_jpeg",
.min_signal = 15,
.max_signal = 15,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "uart1_rx",
.min_signal = 0,
.max_signal = 0,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "uart1_tx",
.min_signal = 1,
.max_signal = 1,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "uart2_rx",
.min_signal = 2,
.max_signal = 2,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "uart2_tx",
.min_signal = 3,
.max_signal = 3,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "uart3_rx",
.min_signal = 4,
.max_signal = 4,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "uart3_tx",
.min_signal = 5,
.max_signal = 5,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "uart4_rx",
.min_signal = 6,
.max_signal = 6,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "uart4_tx",
.min_signal = 7,
.max_signal = 7,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "uart5_rx",
.min_signal = 8,
.max_signal = 8,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "uart5_tx",
.min_signal = 9,
.max_signal = 9,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras5_rx",
.min_signal = 10,
.max_signal = 10,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras5_tx",
.min_signal = 11,
.max_signal = 11,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras6_rx",
.min_signal = 12,
.max_signal = 12,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras6_tx",
.min_signal = 13,
.max_signal = 13,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras7_rx",
.min_signal = 14,
.max_signal = 14,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras7_tx",
.min_signal = 15,
.max_signal = 15,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
},
};
diff --git a/arch/arm/mach-spear3xx/spear320.c b/arch/arm/mach-spear3xx/spear320.c
index 88d483bcd66..fd823c62457 100644
--- a/arch/arm/mach-spear3xx/spear320.c
+++ b/arch/arm/mach-spear3xx/spear320.c
@@ -213,182 +213,156 @@ struct pl08x_channel_data spear320_dma_info[] = {
.min_signal = 2,
.max_signal = 2,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "uart0_tx",
.min_signal = 3,
.max_signal = 3,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ssp0_rx",
.min_signal = 8,
.max_signal = 8,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ssp0_tx",
.min_signal = 9,
.max_signal = 9,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "i2c0_rx",
.min_signal = 10,
.max_signal = 10,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "i2c0_tx",
.min_signal = 11,
.max_signal = 11,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "irda",
.min_signal = 12,
.max_signal = 12,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "adc",
.min_signal = 13,
.max_signal = 13,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "to_jpeg",
.min_signal = 14,
.max_signal = 14,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "from_jpeg",
.min_signal = 15,
.max_signal = 15,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ssp1_rx",
.min_signal = 0,
.max_signal = 0,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ssp1_tx",
.min_signal = 1,
.max_signal = 1,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ssp2_rx",
.min_signal = 2,
.max_signal = 2,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ssp2_tx",
.min_signal = 3,
.max_signal = 3,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "uart1_rx",
.min_signal = 4,
.max_signal = 4,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "uart1_tx",
.min_signal = 5,
.max_signal = 5,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "uart2_rx",
.min_signal = 6,
.max_signal = 6,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "uart2_tx",
.min_signal = 7,
.max_signal = 7,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "i2c1_rx",
.min_signal = 8,
.max_signal = 8,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "i2c1_tx",
.min_signal = 9,
.max_signal = 9,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "i2c2_rx",
.min_signal = 10,
.max_signal = 10,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "i2c2_tx",
.min_signal = 11,
.max_signal = 11,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "i2s_rx",
.min_signal = 12,
.max_signal = 12,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "i2s_tx",
.min_signal = 13,
.max_signal = 13,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "rs485_rx",
.min_signal = 14,
.max_signal = 14,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "rs485_tx",
.min_signal = 15,
.max_signal = 15,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
},
};
diff --git a/arch/arm/mach-spear3xx/spear3xx.c b/arch/arm/mach-spear3xx/spear3xx.c
index 66db5f13af8..98144baf888 100644
--- a/arch/arm/mach-spear3xx/spear3xx.c
+++ b/arch/arm/mach-spear3xx/spear3xx.c
@@ -46,7 +46,8 @@ struct pl022_ssp_controller pl022_plat_data = {
struct pl08x_platform_data pl080_plat_data = {
.memcpy_channel = {
.bus_id = "memcpy",
- .cctl = (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
+ .cctl_memcpy =
+ (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \
PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \
PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \
diff --git a/arch/arm/mach-spear6xx/spear6xx.c b/arch/arm/mach-spear6xx/spear6xx.c
index 9af67d003c6..5a5a52db252 100644
--- a/arch/arm/mach-spear6xx/spear6xx.c
+++ b/arch/arm/mach-spear6xx/spear6xx.c
@@ -36,336 +36,288 @@ static struct pl08x_channel_data spear600_dma_info[] = {
.min_signal = 0,
.max_signal = 0,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ssp1_tx",
.min_signal = 1,
.max_signal = 1,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "uart0_rx",
.min_signal = 2,
.max_signal = 2,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "uart0_tx",
.min_signal = 3,
.max_signal = 3,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "uart1_rx",
.min_signal = 4,
.max_signal = 4,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "uart1_tx",
.min_signal = 5,
.max_signal = 5,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ssp2_rx",
.min_signal = 6,
.max_signal = 6,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ssp2_tx",
.min_signal = 7,
.max_signal = 7,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ssp0_rx",
.min_signal = 8,
.max_signal = 8,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ssp0_tx",
.min_signal = 9,
.max_signal = 9,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "i2c_rx",
.min_signal = 10,
.max_signal = 10,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "i2c_tx",
.min_signal = 11,
.max_signal = 11,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "irda",
.min_signal = 12,
.max_signal = 12,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "adc",
.min_signal = 13,
.max_signal = 13,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "to_jpeg",
.min_signal = 14,
.max_signal = 14,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "from_jpeg",
.min_signal = 15,
.max_signal = 15,
.muxval = 0,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras0_rx",
.min_signal = 0,
.max_signal = 0,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras0_tx",
.min_signal = 1,
.max_signal = 1,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras1_rx",
.min_signal = 2,
.max_signal = 2,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras1_tx",
.min_signal = 3,
.max_signal = 3,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras2_rx",
.min_signal = 4,
.max_signal = 4,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras2_tx",
.min_signal = 5,
.max_signal = 5,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras3_rx",
.min_signal = 6,
.max_signal = 6,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras3_tx",
.min_signal = 7,
.max_signal = 7,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras4_rx",
.min_signal = 8,
.max_signal = 8,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras4_tx",
.min_signal = 9,
.max_signal = 9,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras5_rx",
.min_signal = 10,
.max_signal = 10,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras5_tx",
.min_signal = 11,
.max_signal = 11,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras6_rx",
.min_signal = 12,
.max_signal = 12,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras6_tx",
.min_signal = 13,
.max_signal = 13,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras7_rx",
.min_signal = 14,
.max_signal = 14,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ras7_tx",
.min_signal = 15,
.max_signal = 15,
.muxval = 1,
- .cctl = 0,
.periph_buses = PL08X_AHB1,
}, {
.bus_id = "ext0_rx",
.min_signal = 0,
.max_signal = 0,
.muxval = 2,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ext0_tx",
.min_signal = 1,
.max_signal = 1,
.muxval = 2,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ext1_rx",
.min_signal = 2,
.max_signal = 2,
.muxval = 2,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ext1_tx",
.min_signal = 3,
.max_signal = 3,
.muxval = 2,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ext2_rx",
.min_signal = 4,
.max_signal = 4,
.muxval = 2,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ext2_tx",
.min_signal = 5,
.max_signal = 5,
.muxval = 2,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ext3_rx",
.min_signal = 6,
.max_signal = 6,
.muxval = 2,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ext3_tx",
.min_signal = 7,
.max_signal = 7,
.muxval = 2,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ext4_rx",
.min_signal = 8,
.max_signal = 8,
.muxval = 2,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ext4_tx",
.min_signal = 9,
.max_signal = 9,
.muxval = 2,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ext5_rx",
.min_signal = 10,
.max_signal = 10,
.muxval = 2,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ext5_tx",
.min_signal = 11,
.max_signal = 11,
.muxval = 2,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ext6_rx",
.min_signal = 12,
.max_signal = 12,
.muxval = 2,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ext6_tx",
.min_signal = 13,
.max_signal = 13,
.muxval = 2,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ext7_rx",
.min_signal = 14,
.max_signal = 14,
.muxval = 2,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
}, {
.bus_id = "ext7_tx",
.min_signal = 15,
.max_signal = 15,
.muxval = 2,
- .cctl = 0,
.periph_buses = PL08X_AHB2,
},
};
@@ -373,7 +325,8 @@ static struct pl08x_channel_data spear600_dma_info[] = {
struct pl08x_platform_data pl080_plat_data = {
.memcpy_channel = {
.bus_id = "memcpy",
- .cctl = (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
+ .cctl_memcpy =
+ (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \
PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \
PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \
diff --git a/arch/arm/mach-tegra/board-dt-tegra20.c b/arch/arm/mach-tegra/board-dt-tegra20.c
index d0de9c1192f..c0999633a9a 100644
--- a/arch/arm/mach-tegra/board-dt-tegra20.c
+++ b/arch/arm/mach-tegra/board-dt-tegra20.c
@@ -64,7 +64,8 @@ struct of_dev_auxdata tegra20_auxdata_lookup[] __initdata = {
&tegra_ehci2_pdata),
OF_DEV_AUXDATA("nvidia,tegra20-ehci", TEGRA_USB3_BASE, "tegra-ehci.2",
&tegra_ehci3_pdata),
- OF_DEV_AUXDATA("nvidia,tegra20-apbdma", 0x6000a000, "tegra-apbdma", NULL),
+ OF_DEV_AUXDATA("nvidia,tegra20-apbdma", TEGRA_APB_DMA_BASE, "tegra-apbdma", NULL),
+ OF_DEV_AUXDATA("nvidia,tegra20-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL),
{}
};
diff --git a/arch/arm/mach-tegra/board-dt-tegra30.c b/arch/arm/mach-tegra/board-dt-tegra30.c
index ee48214bfd8..53bf60f1158 100644
--- a/arch/arm/mach-tegra/board-dt-tegra30.c
+++ b/arch/arm/mach-tegra/board-dt-tegra30.c
@@ -33,6 +33,8 @@
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
+#include <mach/iomap.h>
+
#include "board.h"
#include "clock.h"
@@ -48,6 +50,7 @@ struct of_dev_auxdata tegra30_auxdata_lookup[] __initdata = {
OF_DEV_AUXDATA("nvidia,tegra20-i2c", 0x7000D000, "tegra-i2c.4", NULL),
OF_DEV_AUXDATA("nvidia,tegra30-ahub", 0x70080000, "tegra30-ahub", NULL),
OF_DEV_AUXDATA("nvidia,tegra30-apbdma", 0x6000a000, "tegra-apbdma", NULL),
+ OF_DEV_AUXDATA("nvidia,tegra30-pwm", TEGRA_PWFM_BASE, "tegra-pwm", NULL),
{}
};
diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c
index a310222951d..8674a890fd1 100644
--- a/arch/arm/mach-ux500/board-mop500.c
+++ b/arch/arm/mach-ux500/board-mop500.c
@@ -15,6 +15,7 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/i2c.h>
+#include <linux/platform_data/i2c-nomadik.h>
#include <linux/gpio.h>
#include <linux/amba/bus.h>
#include <linux/amba/pl022.h>
@@ -40,7 +41,6 @@
#include <asm/mach/arch.h>
#include <asm/hardware/gic.h>
-#include <plat/i2c.h>
#include <plat/ste_dma40.h>
#include <plat/gpio-nomadik.h>
@@ -211,24 +211,6 @@ static struct ab8500_platform_data ab8500_platdata = {
.codec = &ab8500_codec_pdata,
};
-static struct resource ab8500_resources[] = {
- [0] = {
- .start = IRQ_DB8500_AB8500,
- .end = IRQ_DB8500_AB8500,
- .flags = IORESOURCE_IRQ
- }
-};
-
-struct platform_device ab8500_device = {
- .name = "ab8500-core",
- .id = 0,
- .dev = {
- .platform_data = &ab8500_platdata,
- },
- .num_resources = 1,
- .resource = ab8500_resources,
-};
-
/*
* TPS61052
*/
@@ -443,7 +425,6 @@ static struct hash_platform_data u8500_hash1_platform_data = {
/* add any platform devices here - TODO */
static struct platform_device *mop500_platform_devs[] __initdata = {
&mop500_gpio_keys_device,
- &ab8500_device,
};
#ifdef CONFIG_STE_DMA40
@@ -605,7 +586,6 @@ static struct platform_device *snowball_platform_devs[] __initdata = {
&snowball_led_dev,
&snowball_key_dev,
&snowball_sbnet_dev,
- &ab8500_device,
};
static void __init mop500_init_machine(void)
@@ -617,9 +597,8 @@ static void __init mop500_init_machine(void)
mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR;
mop500_pinmaps_init();
- parent = u8500_init_devices();
+ parent = u8500_init_devices(&ab8500_platdata);
- /* FIXME: parent of ab8500 should be prcmu */
for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)
mop500_platform_devs[i]->dev.parent = parent;
@@ -652,7 +631,7 @@ static void __init snowball_init_machine(void)
int i;
snowball_pinmaps_init();
- parent = u8500_init_devices();
+ parent = u8500_init_devices(&ab8500_platdata);
for (i = 0; i < ARRAY_SIZE(snowball_platform_devs); i++)
snowball_platform_devs[i]->dev.parent = parent;
@@ -684,7 +663,7 @@ static void __init hrefv60_init_machine(void)
mop500_gpio_keys[0].gpio = HREFV60_PROX_SENSE_GPIO;
hrefv60_pinmaps_init();
- parent = u8500_init_devices();
+ parent = u8500_init_devices(&ab8500_platdata);
for (i = 0; i < ARRAY_SIZE(mop500_platform_devs); i++)
mop500_platform_devs[i]->dev.parent = parent;
@@ -785,9 +764,6 @@ static const struct of_device_id u8500_local_bus_nodes[] = {
/* only create devices below soc node */
{ .compatible = "stericsson,db8500", },
{ .compatible = "stericsson,db8500-prcmu", },
- { .compatible = "stericsson,db8500-prcmu-regulator", },
- { .compatible = "stericsson,ab8500", },
- { .compatible = "stericsson,ab8500-regulator", },
{ .compatible = "simple-bus"},
{ },
};
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index c8dd94f606d..db3c52d56ca 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -16,6 +16,7 @@
#include <linux/irq.h>
#include <linux/platform_device.h>
#include <linux/io.h>
+#include <linux/mfd/abx500/ab8500.h>
#include <asm/mach/map.h>
#include <asm/pmu.h>
@@ -115,7 +116,7 @@ static irqreturn_t db8500_pmu_handler(int irq, void *dev, irq_handler_t handler)
return ret;
}
-static struct arm_pmu_platdata db8500_pmu_platdata = {
+struct arm_pmu_platdata db8500_pmu_platdata = {
.handle_irq = db8500_pmu_handler,
};
@@ -206,7 +207,7 @@ static struct device * __init db8500_soc_device_init(void)
/*
* This function is called from the board init
*/
-struct device * __init u8500_init_devices(void)
+struct device * __init u8500_init_devices(struct ab8500_platform_data *ab8500)
{
struct device *parent;
int i;
@@ -223,6 +224,8 @@ struct device * __init u8500_init_devices(void)
for (i = 0; i < ARRAY_SIZE(platform_devs); i++)
platform_devs[i]->dev.parent = parent;
+ db8500_prcmu_device.dev.platform_data = ab8500;
+
platform_add_devices(platform_devs, ARRAY_SIZE(platform_devs));
return parent;
diff --git a/arch/arm/mach-ux500/devices-common.h b/arch/arm/mach-ux500/devices-common.h
index 6e470656026..ecdd8386cff 100644
--- a/arch/arm/mach-ux500/devices-common.h
+++ b/arch/arm/mach-ux500/devices-common.h
@@ -12,7 +12,7 @@
#include <linux/dma-mapping.h>
#include <linux/sys_soc.h>
#include <linux/amba/bus.h>
-#include <plat/i2c.h>
+#include <linux/platform_data/i2c-nomadik.h>
#include <mach/crypto-ux500.h>
struct spi_master_cntlr;
@@ -56,27 +56,15 @@ dbx500_add_uart(struct device *parent, const char *name, resource_size_t base,
struct nmk_i2c_controller;
-static inline struct platform_device *
+static inline struct amba_device *
dbx500_add_i2c(struct device *parent, int id, resource_size_t base, int irq,
struct nmk_i2c_controller *data)
{
- struct resource res[] = {
- DEFINE_RES_MEM(base, SZ_4K),
- DEFINE_RES_IRQ(irq),
- };
+ /* Conjure a name similar to what the platform device used to have */
+ char name[16];
- struct platform_device_info pdevinfo = {
- .parent = parent,
- .name = "nmk-i2c",
- .id = id,
- .res = res,
- .num_res = ARRAY_SIZE(res),
- .data = data,
- .size_data = sizeof(*data),
- .dma_mask = DMA_BIT_MASK(32),
- };
-
- return platform_device_register_full(&pdevinfo);
+ snprintf(name, sizeof(name), "nmk-i2c.%d", id);
+ return amba_apb_device_add(parent, name, base, SZ_4K, irq, 0, data, 0);
}
static inline struct amba_device *
diff --git a/arch/arm/mach-ux500/include/mach/setup.h b/arch/arm/mach-ux500/include/mach/setup.h
index 8b7ed82a286..7914e5eaa9c 100644
--- a/arch/arm/mach-ux500/include/mach/setup.h
+++ b/arch/arm/mach-ux500/include/mach/setup.h
@@ -13,11 +13,12 @@
#include <asm/mach/time.h>
#include <linux/init.h>
+#include <linux/mfd/abx500/ab8500.h>
void __init ux500_map_io(void);
extern void __init u8500_map_io(void);
-extern struct device * __init u8500_init_devices(void);
+extern struct device * __init u8500_init_devices(struct ab8500_platform_data *ab8500);
extern void __init ux500_init_irq(void);
extern void __init ux500_init_late(void);
diff --git a/arch/arm/mach-vt8500/Makefile b/arch/arm/mach-vt8500/Makefile
index 54e69973f39..7ce51767c99 100644
--- a/arch/arm/mach-vt8500/Makefile
+++ b/arch/arm/mach-vt8500/Makefile
@@ -5,5 +5,3 @@ obj-$(CONFIG_VTWM_VERSION_WM8505) += devices-wm8505.o
obj-$(CONFIG_MACH_BV07) += bv07.o
obj-$(CONFIG_MACH_WM8505_7IN_NETBOOK) += wm8505_7in.o
-
-obj-$(CONFIG_HAVE_PWM) += pwm.o
diff --git a/arch/arm/mach-vt8500/pwm.c b/arch/arm/mach-vt8500/pwm.c
deleted file mode 100644
index 8ad825e9359..00000000000
--- a/arch/arm/mach-vt8500/pwm.c
+++ /dev/null
@@ -1,265 +0,0 @@
-/*
- * arch/arm/mach-vt8500/pwm.c
- *
- * Copyright (C) 2010 Alexey Charkov <alchark@gmail.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/io.h>
-#include <linux/pwm.h>
-#include <linux/delay.h>
-
-#include <asm/div64.h>
-
-#define VT8500_NR_PWMS 4
-
-static DEFINE_MUTEX(pwm_lock);
-static LIST_HEAD(pwm_list);
-
-struct pwm_device {
- struct list_head node;
- struct platform_device *pdev;
-
- const char *label;
-
- void __iomem *regbase;
-
- unsigned int use_count;
- unsigned int pwm_id;
-};
-
-#define msecs_to_loops(t) (loops_per_jiffy / 1000 * HZ * t)
-static inline void pwm_busy_wait(void __iomem *reg, u8 bitmask)
-{
- int loops = msecs_to_loops(10);
- while ((readb(reg) & bitmask) && --loops)
- cpu_relax();
-
- if (unlikely(!loops))
- pr_warning("Waiting for status bits 0x%x to clear timed out\n",
- bitmask);
-}
-
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
- unsigned long long c;
- unsigned long period_cycles, prescale, pv, dc;
-
- if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
- return -EINVAL;
-
- c = 25000000/2; /* wild guess --- need to implement clocks */
- c = c * period_ns;
- do_div(c, 1000000000);
- period_cycles = c;
-
- if (period_cycles < 1)
- period_cycles = 1;
- prescale = (period_cycles - 1) / 4096;
- pv = period_cycles / (prescale + 1) - 1;
- if (pv > 4095)
- pv = 4095;
-
- if (prescale > 1023)
- return -EINVAL;
-
- c = (unsigned long long)pv * duty_ns;
- do_div(c, period_ns);
- dc = c;
-
- pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 1));
- writel(prescale, pwm->regbase + 0x4 + (pwm->pwm_id << 4));
-
- pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 2));
- writel(pv, pwm->regbase + 0x8 + (pwm->pwm_id << 4));
-
- pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 3));
- writel(dc, pwm->regbase + 0xc + (pwm->pwm_id << 4));
-
- return 0;
-}
-EXPORT_SYMBOL(pwm_config);
-
-int pwm_enable(struct pwm_device *pwm)
-{
- pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 0));
- writel(5, pwm->regbase + (pwm->pwm_id << 4));
- return 0;
-}
-EXPORT_SYMBOL(pwm_enable);
-
-void pwm_disable(struct pwm_device *pwm)
-{
- pwm_busy_wait(pwm->regbase + 0x40 + pwm->pwm_id, (1 << 0));
- writel(0, pwm->regbase + (pwm->pwm_id << 4));
-}
-EXPORT_SYMBOL(pwm_disable);
-
-struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
- struct pwm_device *pwm;
- int found = 0;
-
- mutex_lock(&pwm_lock);
-
- list_for_each_entry(pwm, &pwm_list, node) {
- if (pwm->pwm_id == pwm_id) {
- found = 1;
- break;
- }
- }
-
- if (found) {
- if (pwm->use_count == 0) {
- pwm->use_count++;
- pwm->label = label;
- } else {
- pwm = ERR_PTR(-EBUSY);
- }
- } else {
- pwm = ERR_PTR(-ENOENT);
- }
-
- mutex_unlock(&pwm_lock);
- return pwm;
-}
-EXPORT_SYMBOL(pwm_request);
-
-void pwm_free(struct pwm_device *pwm)
-{
- mutex_lock(&pwm_lock);
-
- if (pwm->use_count) {
- pwm->use_count--;
- pwm->label = NULL;
- } else {
- pr_warning("PWM device already freed\n");
- }
-
- mutex_unlock(&pwm_lock);
-}
-EXPORT_SYMBOL(pwm_free);
-
-static inline void __add_pwm(struct pwm_device *pwm)
-{
- mutex_lock(&pwm_lock);
- list_add_tail(&pwm->node, &pwm_list);
- mutex_unlock(&pwm_lock);
-}
-
-static int __devinit pwm_probe(struct platform_device *pdev)
-{
- struct pwm_device *pwms;
- struct resource *r;
- int ret = 0;
- int i;
-
- pwms = kzalloc(sizeof(struct pwm_device) * VT8500_NR_PWMS, GFP_KERNEL);
- if (pwms == NULL) {
- dev_err(&pdev->dev, "failed to allocate memory\n");
- return -ENOMEM;
- }
-
- for (i = 0; i < VT8500_NR_PWMS; i++) {
- pwms[i].use_count = 0;
- pwms[i].pwm_id = i;
- pwms[i].pdev = pdev;
- }
-
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (r == NULL) {
- dev_err(&pdev->dev, "no memory resource defined\n");
- ret = -ENODEV;
- goto err_free;
- }
-
- r = request_mem_region(r->start, resource_size(r), pdev->name);
- if (r == NULL) {
- dev_err(&pdev->dev, "failed to request memory resource\n");
- ret = -EBUSY;
- goto err_free;
- }
-
- pwms[0].regbase = ioremap(r->start, resource_size(r));
- if (pwms[0].regbase == NULL) {
- dev_err(&pdev->dev, "failed to ioremap() registers\n");
- ret = -ENODEV;
- goto err_free_mem;
- }
-
- for (i = 1; i < VT8500_NR_PWMS; i++)
- pwms[i].regbase = pwms[0].regbase;
-
- for (i = 0; i < VT8500_NR_PWMS; i++)
- __add_pwm(&pwms[i]);
-
- platform_set_drvdata(pdev, pwms);
- return 0;
-
-err_free_mem:
- release_mem_region(r->start, resource_size(r));
-err_free:
- kfree(pwms);
- return ret;
-}
-
-static int __devexit pwm_remove(struct platform_device *pdev)
-{
- struct pwm_device *pwms;
- struct resource *r;
- int i;
-
- pwms = platform_get_drvdata(pdev);
- if (pwms == NULL)
- return -ENODEV;
-
- mutex_lock(&pwm_lock);
-
- for (i = 0; i < VT8500_NR_PWMS; i++)
- list_del(&pwms[i].node);
- mutex_unlock(&pwm_lock);
-
- iounmap(pwms[0].regbase);
-
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(r->start, resource_size(r));
-
- kfree(pwms);
- return 0;
-}
-
-static struct platform_driver pwm_driver = {
- .driver = {
- .name = "vt8500-pwm",
- .owner = THIS_MODULE,
- },
- .probe = pwm_probe,
- .remove = __devexit_p(pwm_remove),
-};
-
-static int __init pwm_init(void)
-{
- return platform_driver_register(&pwm_driver);
-}
-arch_initcall(pwm_init);
-
-static void __exit pwm_exit(void)
-{
- platform_driver_unregister(&pwm_driver);
-}
-module_exit(pwm_exit);
-
-MODULE_LICENSE("GPL");
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 5cfc9899407..c2cdf6500f7 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -22,6 +22,7 @@
#include <linux/memblock.h>
#include <linux/slab.h>
#include <linux/iommu.h>
+#include <linux/io.h>
#include <linux/vmalloc.h>
#include <linux/sizes.h>
@@ -72,7 +73,7 @@ static dma_addr_t arm_dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, enum dma_data_direction dir,
struct dma_attrs *attrs)
{
- if (!arch_is_coherent())
+ if (!arch_is_coherent() && !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
__dma_page_cpu_to_dev(page, offset, size, dir);
return pfn_to_dma(dev, page_to_pfn(page)) + offset;
}
@@ -95,7 +96,7 @@ static void arm_dma_unmap_page(struct device *dev, dma_addr_t handle,
size_t size, enum dma_data_direction dir,
struct dma_attrs *attrs)
{
- if (!arch_is_coherent())
+ if (!arch_is_coherent() && !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
__dma_page_dev_to_cpu(pfn_to_page(dma_to_pfn(dev, handle)),
handle & ~PAGE_MASK, size, dir);
}
@@ -124,6 +125,7 @@ struct dma_map_ops arm_dma_ops = {
.alloc = arm_dma_alloc,
.free = arm_dma_free,
.mmap = arm_dma_mmap,
+ .get_sgtable = arm_dma_get_sgtable,
.map_page = arm_dma_map_page,
.unmap_page = arm_dma_unmap_page,
.map_sg = arm_dma_map_sg,
@@ -217,115 +219,70 @@ static void __dma_free_buffer(struct page *page, size_t size)
}
#ifdef CONFIG_MMU
+#ifdef CONFIG_HUGETLB_PAGE
+#error ARM Coherent DMA allocator does not (yet) support huge TLB
+#endif
-#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - consistent_base) >> PAGE_SHIFT)
-#define CONSISTENT_PTE_INDEX(x) (((unsigned long)(x) - consistent_base) >> PMD_SHIFT)
-
-/*
- * These are the page tables (2MB each) covering uncached, DMA consistent allocations
- */
-static pte_t **consistent_pte;
-
-#define DEFAULT_CONSISTENT_DMA_SIZE SZ_2M
+static void *__alloc_from_contiguous(struct device *dev, size_t size,
+ pgprot_t prot, struct page **ret_page);
-static unsigned long consistent_base = CONSISTENT_END - DEFAULT_CONSISTENT_DMA_SIZE;
+static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
+ pgprot_t prot, struct page **ret_page,
+ const void *caller);
-void __init init_consistent_dma_size(unsigned long size)
+static void *
+__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
+ const void *caller)
{
- unsigned long base = CONSISTENT_END - ALIGN(size, SZ_2M);
+ struct vm_struct *area;
+ unsigned long addr;
- BUG_ON(consistent_pte); /* Check we're called before DMA region init */
- BUG_ON(base < VMALLOC_END);
+ /*
+ * DMA allocation can be mapped to user space, so lets
+ * set VM_USERMAP flags too.
+ */
+ area = get_vm_area_caller(size, VM_ARM_DMA_CONSISTENT | VM_USERMAP,
+ caller);
+ if (!area)
+ return NULL;
+ addr = (unsigned long)area->addr;
+ area->phys_addr = __pfn_to_phys(page_to_pfn(page));
- /* Grow region to accommodate specified size */
- if (base < consistent_base)
- consistent_base = base;
+ if (ioremap_page_range(addr, addr + size, area->phys_addr, prot)) {
+ vunmap((void *)addr);
+ return NULL;
+ }
+ return (void *)addr;
}
-#include "vmregion.h"
-
-static struct arm_vmregion_head consistent_head = {
- .vm_lock = __SPIN_LOCK_UNLOCKED(&consistent_head.vm_lock),
- .vm_list = LIST_HEAD_INIT(consistent_head.vm_list),
- .vm_end = CONSISTENT_END,
-};
-
-#ifdef CONFIG_HUGETLB_PAGE
-#error ARM Coherent DMA allocator does not (yet) support huge TLB
-#endif
-
-/*
- * Initialise the consistent memory allocation.
- */
-static int __init consistent_init(void)
+static void __dma_free_remap(void *cpu_addr, size_t size)
{
- int ret = 0;
- pgd_t *pgd;
- pud_t *pud;
- pmd_t *pmd;
- pte_t *pte;
- int i = 0;
- unsigned long base = consistent_base;
- unsigned long num_ptes = (CONSISTENT_END - base) >> PMD_SHIFT;
-
- if (IS_ENABLED(CONFIG_CMA) && !IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU))
- return 0;
-
- consistent_pte = kmalloc(num_ptes * sizeof(pte_t), GFP_KERNEL);
- if (!consistent_pte) {
- pr_err("%s: no memory\n", __func__);
- return -ENOMEM;
+ unsigned int flags = VM_ARM_DMA_CONSISTENT | VM_USERMAP;
+ struct vm_struct *area = find_vm_area(cpu_addr);
+ if (!area || (area->flags & flags) != flags) {
+ WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr);
+ return;
}
-
- pr_debug("DMA memory: 0x%08lx - 0x%08lx:\n", base, CONSISTENT_END);
- consistent_head.vm_start = base;
-
- do {
- pgd = pgd_offset(&init_mm, base);
-
- pud = pud_alloc(&init_mm, pgd, base);
- if (!pud) {
- pr_err("%s: no pud tables\n", __func__);
- ret = -ENOMEM;
- break;
- }
-
- pmd = pmd_alloc(&init_mm, pud, base);
- if (!pmd) {
- pr_err("%s: no pmd tables\n", __func__);
- ret = -ENOMEM;
- break;
- }
- WARN_ON(!pmd_none(*pmd));
-
- pte = pte_alloc_kernel(pmd, base);
- if (!pte) {
- pr_err("%s: no pte tables\n", __func__);
- ret = -ENOMEM;
- break;
- }
-
- consistent_pte[i++] = pte;
- base += PMD_SIZE;
- } while (base < CONSISTENT_END);
-
- return ret;
+ unmap_kernel_range((unsigned long)cpu_addr, size);
+ vunmap(cpu_addr);
}
-core_initcall(consistent_init);
-static void *__alloc_from_contiguous(struct device *dev, size_t size,
- pgprot_t prot, struct page **ret_page);
-
-static struct arm_vmregion_head coherent_head = {
- .vm_lock = __SPIN_LOCK_UNLOCKED(&coherent_head.vm_lock),
- .vm_list = LIST_HEAD_INIT(coherent_head.vm_list),
+struct dma_pool {
+ size_t size;
+ spinlock_t lock;
+ unsigned long *bitmap;
+ unsigned long nr_pages;
+ void *vaddr;
+ struct page *page;
};
-static size_t coherent_pool_size = DEFAULT_CONSISTENT_DMA_SIZE / 8;
+static struct dma_pool atomic_pool = {
+ .size = SZ_256K,
+};
static int __init early_coherent_pool(char *p)
{
- coherent_pool_size = memparse(p, &p);
+ atomic_pool.size = memparse(p, &p);
return 0;
}
early_param("coherent_pool", early_coherent_pool);
@@ -333,32 +290,45 @@ early_param("coherent_pool", early_coherent_pool);
/*
* Initialise the coherent pool for atomic allocations.
*/
-static int __init coherent_init(void)
+static int __init atomic_pool_init(void)
{
+ struct dma_pool *pool = &atomic_pool;
pgprot_t prot = pgprot_dmacoherent(pgprot_kernel);
- size_t size = coherent_pool_size;
+ unsigned long nr_pages = pool->size >> PAGE_SHIFT;
+ unsigned long *bitmap;
struct page *page;
void *ptr;
+ int bitmap_size = BITS_TO_LONGS(nr_pages) * sizeof(long);
- if (!IS_ENABLED(CONFIG_CMA))
- return 0;
+ bitmap = kzalloc(bitmap_size, GFP_KERNEL);
+ if (!bitmap)
+ goto no_bitmap;
- ptr = __alloc_from_contiguous(NULL, size, prot, &page);
+ if (IS_ENABLED(CONFIG_CMA))
+ ptr = __alloc_from_contiguous(NULL, pool->size, prot, &page);
+ else
+ ptr = __alloc_remap_buffer(NULL, pool->size, GFP_KERNEL, prot,
+ &page, NULL);
if (ptr) {
- coherent_head.vm_start = (unsigned long) ptr;
- coherent_head.vm_end = (unsigned long) ptr + size;
- printk(KERN_INFO "DMA: preallocated %u KiB pool for atomic coherent allocations\n",
- (unsigned)size / 1024);
+ spin_lock_init(&pool->lock);
+ pool->vaddr = ptr;
+ pool->page = page;
+ pool->bitmap = bitmap;
+ pool->nr_pages = nr_pages;
+ pr_info("DMA: preallocated %u KiB pool for atomic coherent allocations\n",
+ (unsigned)pool->size / 1024);
return 0;
}
- printk(KERN_ERR "DMA: failed to allocate %u KiB pool for atomic coherent allocation\n",
- (unsigned)size / 1024);
+ kfree(bitmap);
+no_bitmap:
+ pr_err("DMA: failed to allocate %u KiB pool for atomic coherent allocation\n",
+ (unsigned)pool->size / 1024);
return -ENOMEM;
}
/*
* CMA is activated by core_initcall, so we must be called after it.
*/
-postcore_initcall(coherent_init);
+postcore_initcall(atomic_pool_init);
struct dma_contig_early_reserve {
phys_addr_t base;
@@ -406,112 +376,6 @@ void __init dma_contiguous_remap(void)
}
}
-static void *
-__dma_alloc_remap(struct page *page, size_t size, gfp_t gfp, pgprot_t prot,
- const void *caller)
-{
- struct arm_vmregion *c;
- size_t align;
- int bit;
-
- if (!consistent_pte) {
- pr_err("%s: not initialised\n", __func__);
- dump_stack();
- return NULL;
- }
-
- /*
- * Align the virtual region allocation - maximum alignment is
- * a section size, minimum is a page size. This helps reduce
- * fragmentation of the DMA space, and also prevents allocations
- * smaller than a section from crossing a section boundary.
- */
- bit = fls(size - 1);
- if (bit > SECTION_SHIFT)
- bit = SECTION_SHIFT;
- align = 1 << bit;
-
- /*
- * Allocate a virtual address in the consistent mapping region.
- */
- c = arm_vmregion_alloc(&consistent_head, align, size,
- gfp & ~(__GFP_DMA | __GFP_HIGHMEM), caller);
- if (c) {
- pte_t *pte;
- int idx = CONSISTENT_PTE_INDEX(c->vm_start);
- u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
-
- pte = consistent_pte[idx] + off;
- c->priv = page;
-
- do {
- BUG_ON(!pte_none(*pte));
-
- set_pte_ext(pte, mk_pte(page, prot), 0);
- page++;
- pte++;
- off++;
- if (off >= PTRS_PER_PTE) {
- off = 0;
- pte = consistent_pte[++idx];
- }
- } while (size -= PAGE_SIZE);
-
- dsb();
-
- return (void *)c->vm_start;
- }
- return NULL;
-}
-
-static void __dma_free_remap(void *cpu_addr, size_t size)
-{
- struct arm_vmregion *c;
- unsigned long addr;
- pte_t *ptep;
- int idx;
- u32 off;
-
- c = arm_vmregion_find_remove(&consistent_head, (unsigned long)cpu_addr);
- if (!c) {
- pr_err("%s: trying to free invalid coherent area: %p\n",
- __func__, cpu_addr);
- dump_stack();
- return;
- }
-
- if ((c->vm_end - c->vm_start) != size) {
- pr_err("%s: freeing wrong coherent size (%ld != %d)\n",
- __func__, c->vm_end - c->vm_start, size);
- dump_stack();
- size = c->vm_end - c->vm_start;
- }
-
- idx = CONSISTENT_PTE_INDEX(c->vm_start);
- off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
- ptep = consistent_pte[idx] + off;
- addr = c->vm_start;
- do {
- pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep);
-
- ptep++;
- addr += PAGE_SIZE;
- off++;
- if (off >= PTRS_PER_PTE) {
- off = 0;
- ptep = consistent_pte[++idx];
- }
-
- if (pte_none(pte) || !pte_present(pte))
- pr_crit("%s: bad page in kernel page table\n",
- __func__);
- } while (size -= PAGE_SIZE);
-
- flush_tlb_kernel_range(c->vm_start, c->vm_end);
-
- arm_vmregion_free(&consistent_head, c);
-}
-
static int __dma_update_pte(pte_t *pte, pgtable_t token, unsigned long addr,
void *data)
{
@@ -552,16 +416,17 @@ static void *__alloc_remap_buffer(struct device *dev, size_t size, gfp_t gfp,
return ptr;
}
-static void *__alloc_from_pool(struct device *dev, size_t size,
- struct page **ret_page, const void *caller)
+static void *__alloc_from_pool(size_t size, struct page **ret_page)
{
- struct arm_vmregion *c;
+ struct dma_pool *pool = &atomic_pool;
+ unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ unsigned int pageno;
+ unsigned long flags;
+ void *ptr = NULL;
size_t align;
- if (!coherent_head.vm_start) {
- printk(KERN_ERR "%s: coherent pool not initialised!\n",
- __func__);
- dump_stack();
+ if (!pool->vaddr) {
+ WARN(1, "coherent pool not initialised!\n");
return NULL;
}
@@ -571,35 +436,41 @@ static void *__alloc_from_pool(struct device *dev, size_t size,
* size. This helps reduce fragmentation of the DMA space.
*/
align = PAGE_SIZE << get_order(size);
- c = arm_vmregion_alloc(&coherent_head, align, size, 0, caller);
- if (c) {
- void *ptr = (void *)c->vm_start;
- struct page *page = virt_to_page(ptr);
- *ret_page = page;
- return ptr;
+
+ spin_lock_irqsave(&pool->lock, flags);
+ pageno = bitmap_find_next_zero_area(pool->bitmap, pool->nr_pages,
+ 0, count, (1 << align) - 1);
+ if (pageno < pool->nr_pages) {
+ bitmap_set(pool->bitmap, pageno, count);
+ ptr = pool->vaddr + PAGE_SIZE * pageno;
+ *ret_page = pool->page + pageno;
}
- return NULL;
+ spin_unlock_irqrestore(&pool->lock, flags);
+
+ return ptr;
}
-static int __free_from_pool(void *cpu_addr, size_t size)
+static int __free_from_pool(void *start, size_t size)
{
- unsigned long start = (unsigned long)cpu_addr;
- unsigned long end = start + size;
- struct arm_vmregion *c;
+ struct dma_pool *pool = &atomic_pool;
+ unsigned long pageno, count;
+ unsigned long flags;
- if (start < coherent_head.vm_start || end > coherent_head.vm_end)
+ if (start < pool->vaddr || start > pool->vaddr + pool->size)
return 0;
- c = arm_vmregion_find_remove(&coherent_head, (unsigned long)start);
-
- if ((c->vm_end - c->vm_start) != size) {
- printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n",
- __func__, c->vm_end - c->vm_start, size);
- dump_stack();
- size = c->vm_end - c->vm_start;
+ if (start + size > pool->vaddr + pool->size) {
+ WARN(1, "freeing wrong coherent size from pool\n");
+ return 0;
}
- arm_vmregion_free(&coherent_head, c);
+ pageno = (start - pool->vaddr) >> PAGE_SHIFT;
+ count = size >> PAGE_SHIFT;
+
+ spin_lock_irqsave(&pool->lock, flags);
+ bitmap_clear(pool->bitmap, pageno, count);
+ spin_unlock_irqrestore(&pool->lock, flags);
+
return 1;
}
@@ -644,7 +515,7 @@ static inline pgprot_t __get_dma_pgprot(struct dma_attrs *attrs, pgprot_t prot)
#define __get_dma_pgprot(attrs, prot) __pgprot(0)
#define __alloc_remap_buffer(dev, size, gfp, prot, ret, c) NULL
-#define __alloc_from_pool(dev, size, ret_page, c) NULL
+#define __alloc_from_pool(size, ret_page) NULL
#define __alloc_from_contiguous(dev, size, prot, ret) NULL
#define __free_from_pool(cpu_addr, size) 0
#define __free_from_contiguous(dev, page, size) do { } while (0)
@@ -702,10 +573,10 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
if (arch_is_coherent() || nommu())
addr = __alloc_simple_buffer(dev, size, gfp, &page);
+ else if (gfp & GFP_ATOMIC)
+ addr = __alloc_from_pool(size, &page);
else if (!IS_ENABLED(CONFIG_CMA))
addr = __alloc_remap_buffer(dev, size, gfp, prot, &page, caller);
- else if (gfp & GFP_ATOMIC)
- addr = __alloc_from_pool(dev, size, &page, caller);
else
addr = __alloc_from_contiguous(dev, size, prot, &page);
@@ -741,16 +612,22 @@ int arm_dma_mmap(struct device *dev, struct vm_area_struct *vma,
{
int ret = -ENXIO;
#ifdef CONFIG_MMU
+ unsigned long nr_vma_pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
+ unsigned long nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
unsigned long pfn = dma_to_pfn(dev, dma_addr);
+ unsigned long off = vma->vm_pgoff;
+
vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
if (dma_mmap_from_coherent(dev, vma, cpu_addr, size, &ret))
return ret;
- ret = remap_pfn_range(vma, vma->vm_start,
- pfn + vma->vm_pgoff,
- vma->vm_end - vma->vm_start,
- vma->vm_page_prot);
+ if (off < nr_pages && nr_vma_pages <= (nr_pages - off)) {
+ ret = remap_pfn_range(vma, vma->vm_start,
+ pfn + off,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+ }
#endif /* CONFIG_MMU */
return ret;
@@ -785,6 +662,21 @@ void arm_dma_free(struct device *dev, size_t size, void *cpu_addr,
}
}
+int arm_dma_get_sgtable(struct device *dev, struct sg_table *sgt,
+ void *cpu_addr, dma_addr_t handle, size_t size,
+ struct dma_attrs *attrs)
+{
+ struct page *page = pfn_to_page(dma_to_pfn(dev, handle));
+ int ret;
+
+ ret = sg_alloc_table(sgt, 1, GFP_KERNEL);
+ if (unlikely(ret))
+ return ret;
+
+ sg_set_page(sgt->sgl, page, PAGE_ALIGN(size), 0);
+ return 0;
+}
+
static void dma_cache_maint_page(struct page *page, unsigned long offset,
size_t size, enum dma_data_direction dir,
void (*op)(const void *, size_t, int))
@@ -998,9 +890,6 @@ static int arm_dma_set_mask(struct device *dev, u64 dma_mask)
static int __init dma_debug_do_init(void)
{
-#ifdef CONFIG_MMU
- arm_vmregion_create_proc("dma-mappings", &consistent_head);
-#endif
dma_debug_init(PREALLOC_DMA_DEBUG_ENTRIES);
return 0;
}
@@ -1088,7 +977,7 @@ static struct page **__iommu_alloc_buffer(struct device *dev, size_t size, gfp_t
return pages;
error:
- while (--i)
+ while (i--)
if (pages[i])
__free_pages(pages[i], 0);
if (array_size <= PAGE_SIZE)
@@ -1117,61 +1006,32 @@ static int __iommu_free_buffer(struct device *dev, struct page **pages, size_t s
* Create a CPU mapping for a specified pages
*/
static void *
-__iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot)
+__iommu_alloc_remap(struct page **pages, size_t size, gfp_t gfp, pgprot_t prot,
+ const void *caller)
{
- struct arm_vmregion *c;
- size_t align;
- size_t count = size >> PAGE_SHIFT;
- int bit;
+ unsigned int i, nr_pages = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ struct vm_struct *area;
+ unsigned long p;
- if (!consistent_pte[0]) {
- pr_err("%s: not initialised\n", __func__);
- dump_stack();
+ area = get_vm_area_caller(size, VM_ARM_DMA_CONSISTENT | VM_USERMAP,
+ caller);
+ if (!area)
return NULL;
- }
-
- /*
- * Align the virtual region allocation - maximum alignment is
- * a section size, minimum is a page size. This helps reduce
- * fragmentation of the DMA space, and also prevents allocations
- * smaller than a section from crossing a section boundary.
- */
- bit = fls(size - 1);
- if (bit > SECTION_SHIFT)
- bit = SECTION_SHIFT;
- align = 1 << bit;
-
- /*
- * Allocate a virtual address in the consistent mapping region.
- */
- c = arm_vmregion_alloc(&consistent_head, align, size,
- gfp & ~(__GFP_DMA | __GFP_HIGHMEM), NULL);
- if (c) {
- pte_t *pte;
- int idx = CONSISTENT_PTE_INDEX(c->vm_start);
- int i = 0;
- u32 off = CONSISTENT_OFFSET(c->vm_start) & (PTRS_PER_PTE-1);
-
- pte = consistent_pte[idx] + off;
- c->priv = pages;
-
- do {
- BUG_ON(!pte_none(*pte));
-
- set_pte_ext(pte, mk_pte(pages[i], prot), 0);
- pte++;
- off++;
- i++;
- if (off >= PTRS_PER_PTE) {
- off = 0;
- pte = consistent_pte[++idx];
- }
- } while (i < count);
- dsb();
+ area->pages = pages;
+ area->nr_pages = nr_pages;
+ p = (unsigned long)area->addr;
- return (void *)c->vm_start;
+ for (i = 0; i < nr_pages; i++) {
+ phys_addr_t phys = __pfn_to_phys(page_to_pfn(pages[i]));
+ if (ioremap_page_range(p, p + PAGE_SIZE, phys, prot))
+ goto err;
+ p += PAGE_SIZE;
}
+ return area->addr;
+err:
+ unmap_kernel_range((unsigned long)area->addr, size);
+ vunmap(area->addr);
return NULL;
}
@@ -1230,6 +1090,19 @@ static int __iommu_remove_mapping(struct device *dev, dma_addr_t iova, size_t si
return 0;
}
+static struct page **__iommu_get_pages(void *cpu_addr, struct dma_attrs *attrs)
+{
+ struct vm_struct *area;
+
+ if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs))
+ return cpu_addr;
+
+ area = find_vm_area(cpu_addr);
+ if (area && (area->flags & VM_ARM_DMA_CONSISTENT))
+ return area->pages;
+ return NULL;
+}
+
static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
{
@@ -1248,7 +1121,11 @@ static void *arm_iommu_alloc_attrs(struct device *dev, size_t size,
if (*handle == DMA_ERROR_CODE)
goto err_buffer;
- addr = __iommu_alloc_remap(pages, size, gfp, prot);
+ if (dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs))
+ return pages;
+
+ addr = __iommu_alloc_remap(pages, size, gfp, prot,
+ __builtin_return_address(0));
if (!addr)
goto err_mapping;
@@ -1265,31 +1142,25 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
void *cpu_addr, dma_addr_t dma_addr, size_t size,
struct dma_attrs *attrs)
{
- struct arm_vmregion *c;
+ unsigned long uaddr = vma->vm_start;
+ unsigned long usize = vma->vm_end - vma->vm_start;
+ struct page **pages = __iommu_get_pages(cpu_addr, attrs);
vma->vm_page_prot = __get_dma_pgprot(attrs, vma->vm_page_prot);
- c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr);
-
- if (c) {
- struct page **pages = c->priv;
-
- unsigned long uaddr = vma->vm_start;
- unsigned long usize = vma->vm_end - vma->vm_start;
- int i = 0;
- do {
- int ret;
+ if (!pages)
+ return -ENXIO;
- ret = vm_insert_page(vma, uaddr, pages[i++]);
- if (ret) {
- pr_err("Remapping memory, error: %d\n", ret);
- return ret;
- }
+ do {
+ int ret = vm_insert_page(vma, uaddr, *pages++);
+ if (ret) {
+ pr_err("Remapping memory failed: %d\n", ret);
+ return ret;
+ }
+ uaddr += PAGE_SIZE;
+ usize -= PAGE_SIZE;
+ } while (usize > 0);
- uaddr += PAGE_SIZE;
- usize -= PAGE_SIZE;
- } while (usize > 0);
- }
return 0;
}
@@ -1300,16 +1171,35 @@ static int arm_iommu_mmap_attrs(struct device *dev, struct vm_area_struct *vma,
void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
dma_addr_t handle, struct dma_attrs *attrs)
{
- struct arm_vmregion *c;
+ struct page **pages = __iommu_get_pages(cpu_addr, attrs);
size = PAGE_ALIGN(size);
- c = arm_vmregion_find(&consistent_head, (unsigned long)cpu_addr);
- if (c) {
- struct page **pages = c->priv;
- __dma_free_remap(cpu_addr, size);
- __iommu_remove_mapping(dev, handle, size);
- __iommu_free_buffer(dev, pages, size);
+ if (!pages) {
+ WARN(1, "trying to free invalid coherent area: %p\n", cpu_addr);
+ return;
}
+
+ if (!dma_get_attr(DMA_ATTR_NO_KERNEL_MAPPING, attrs)) {
+ unmap_kernel_range((unsigned long)cpu_addr, size);
+ vunmap(cpu_addr);
+ }
+
+ __iommu_remove_mapping(dev, handle, size);
+ __iommu_free_buffer(dev, pages, size);
+}
+
+static int arm_iommu_get_sgtable(struct device *dev, struct sg_table *sgt,
+ void *cpu_addr, dma_addr_t dma_addr,
+ size_t size, struct dma_attrs *attrs)
+{
+ unsigned int count = PAGE_ALIGN(size) >> PAGE_SHIFT;
+ struct page **pages = __iommu_get_pages(cpu_addr, attrs);
+
+ if (!pages)
+ return -ENXIO;
+
+ return sg_alloc_table_from_pages(sgt, pages, count, 0, size,
+ GFP_KERNEL);
}
/*
@@ -1317,7 +1207,7 @@ void arm_iommu_free_attrs(struct device *dev, size_t size, void *cpu_addr,
*/
static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
size_t size, dma_addr_t *handle,
- enum dma_data_direction dir)
+ enum dma_data_direction dir, struct dma_attrs *attrs)
{
struct dma_iommu_mapping *mapping = dev->archdata.mapping;
dma_addr_t iova, iova_base;
@@ -1336,7 +1226,8 @@ static int __map_sg_chunk(struct device *dev, struct scatterlist *sg,
phys_addr_t phys = page_to_phys(sg_page(s));
unsigned int len = PAGE_ALIGN(s->offset + s->length);
- if (!arch_is_coherent())
+ if (!arch_is_coherent() &&
+ !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
__dma_page_cpu_to_dev(sg_page(s), s->offset, s->length, dir);
ret = iommu_map(mapping->domain, iova, phys, len, 0);
@@ -1383,7 +1274,7 @@ int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
if (s->offset || (size & ~PAGE_MASK) || size + s->length > max) {
if (__map_sg_chunk(dev, start, size, &dma->dma_address,
- dir) < 0)
+ dir, attrs) < 0)
goto bad_mapping;
dma->dma_address += offset;
@@ -1396,7 +1287,7 @@ int arm_iommu_map_sg(struct device *dev, struct scatterlist *sg, int nents,
}
size += s->length;
}
- if (__map_sg_chunk(dev, start, size, &dma->dma_address, dir) < 0)
+ if (__map_sg_chunk(dev, start, size, &dma->dma_address, dir, attrs) < 0)
goto bad_mapping;
dma->dma_address += offset;
@@ -1430,7 +1321,8 @@ void arm_iommu_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
if (sg_dma_len(s))
__iommu_remove_mapping(dev, sg_dma_address(s),
sg_dma_len(s));
- if (!arch_is_coherent())
+ if (!arch_is_coherent() &&
+ !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
__dma_page_dev_to_cpu(sg_page(s), s->offset,
s->length, dir);
}
@@ -1492,7 +1384,7 @@ static dma_addr_t arm_iommu_map_page(struct device *dev, struct page *page,
dma_addr_t dma_addr;
int ret, len = PAGE_ALIGN(size + offset);
- if (!arch_is_coherent())
+ if (!arch_is_coherent() && !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
__dma_page_cpu_to_dev(page, offset, size, dir);
dma_addr = __alloc_iova(mapping, len);
@@ -1531,7 +1423,7 @@ static void arm_iommu_unmap_page(struct device *dev, dma_addr_t handle,
if (!iova)
return;
- if (!arch_is_coherent())
+ if (!arch_is_coherent() && !dma_get_attr(DMA_ATTR_SKIP_CPU_SYNC, attrs))
__dma_page_dev_to_cpu(page, offset, size, dir);
iommu_unmap(mapping->domain, iova, len);
@@ -1571,6 +1463,7 @@ struct dma_map_ops iommu_ops = {
.alloc = arm_iommu_alloc_attrs,
.free = arm_iommu_free_attrs,
.mmap = arm_iommu_mmap_attrs,
+ .get_sgtable = arm_iommu_get_sgtable,
.map_page = arm_iommu_map_page,
.unmap_page = arm_iommu_unmap_page,
diff --git a/arch/arm/mm/mm.h b/arch/arm/mm/mm.h
index 2e8a1efdf7b..6776160618e 100644
--- a/arch/arm/mm/mm.h
+++ b/arch/arm/mm/mm.h
@@ -59,6 +59,9 @@ extern void __flush_dcache_page(struct address_space *mapping, struct page *page
#define VM_ARM_MTYPE(mt) ((mt) << 20)
#define VM_ARM_MTYPE_MASK (0x1f << 20)
+/* consistent regions used by dma_alloc_attrs() */
+#define VM_ARM_DMA_CONSISTENT 0x20000000
+
#endif
#ifdef CONFIG_ZONE_DMA
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S
index 845f461f8ec..c2021139cb5 100644
--- a/arch/arm/mm/tlb-v7.S
+++ b/arch/arm/mm/tlb-v7.S
@@ -38,11 +38,19 @@ ENTRY(v7wbi_flush_user_tlb_range)
dsb
mov r0, r0, lsr #PAGE_SHIFT @ align address
mov r1, r1, lsr #PAGE_SHIFT
+#ifdef CONFIG_ARM_ERRATA_720789
+ mov r3, #0
+#else
asid r3, r3 @ mask ASID
+#endif
orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA
mov r1, r1, lsl #PAGE_SHIFT
1:
+#ifdef CONFIG_ARM_ERRATA_720789
+ ALT_SMP(mcr p15, 0, r0, c8, c3, 3) @ TLB invalidate U MVA all ASID (shareable)
+#else
ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable)
+#endif
ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA
add r0, r0, #PAGE_SZ
@@ -67,7 +75,11 @@ ENTRY(v7wbi_flush_kern_tlb_range)
mov r0, r0, lsl #PAGE_SHIFT
mov r1, r1, lsl #PAGE_SHIFT
1:
+#ifdef CONFIG_ARM_ERRATA_720789
+ ALT_SMP(mcr p15, 0, r0, c8, c3, 3) @ TLB invalidate U MVA all ASID (shareable)
+#else
ALT_SMP(mcr p15, 0, r0, c8, c3, 1) @ TLB invalidate U MVA (shareable)
+#endif
ALT_UP(mcr p15, 0, r0, c8, c7, 1) @ TLB invalidate U MVA
add r0, r0, #PAGE_SZ
cmp r0, r1
diff --git a/arch/arm/plat-mxc/Kconfig b/arch/arm/plat-mxc/Kconfig
index c722f9ce691..baf9064c084 100644
--- a/arch/arm/plat-mxc/Kconfig
+++ b/arch/arm/plat-mxc/Kconfig
@@ -47,12 +47,6 @@ config MXC_TZIC
config MXC_AVIC
bool
-config MXC_PWM
- tristate "Enable PWM driver"
- select HAVE_PWM
- help
- Enable support for the i.MX PWM controller(s).
-
config MXC_DEBUG_BOARD
bool "Enable MXC debug board(for 3-stack)"
help
diff --git a/arch/arm/plat-mxc/Makefile b/arch/arm/plat-mxc/Makefile
index 63b064b5c1d..6ac72003115 100644
--- a/arch/arm/plat-mxc/Makefile
+++ b/arch/arm/plat-mxc/Makefile
@@ -11,7 +11,6 @@ obj-$(CONFIG_MXC_AVIC) += avic.o
obj-$(CONFIG_IMX_HAVE_IOMUX_V1) += iomux-v1.o
obj-$(CONFIG_ARCH_MXC_IOMUX_V3) += iomux-v3.o
obj-$(CONFIG_IRAM_ALLOC) += iram_alloc.o
-obj-$(CONFIG_MXC_PWM) += pwm.o
obj-$(CONFIG_MXC_ULPI) += ulpi.o
obj-$(CONFIG_MXC_USE_EPIT) += epit.o
obj-$(CONFIG_MXC_DEBUG_BOARD) += 3ds_debugboard.o
diff --git a/arch/arm/plat-mxc/include/mach/i2c.h b/arch/arm/plat-mxc/include/mach/i2c.h
index 375cdd0cf87..8289d915e61 100644
--- a/arch/arm/plat-mxc/include/mach/i2c.h
+++ b/arch/arm/plat-mxc/include/mach/i2c.h
@@ -15,7 +15,7 @@
*
**/
struct imxi2c_platform_data {
- int bitrate;
+ u32 bitrate;
};
#endif /* __ASM_ARCH_I2C_H_ */
diff --git a/arch/arm/plat-mxc/pwm.c b/arch/arm/plat-mxc/pwm.c
deleted file mode 100644
index c0cab2270dd..00000000000
--- a/arch/arm/plat-mxc/pwm.c
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * simple driver for PWM (Pulse Width Modulator) controller
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Derived from pxa PWM driver by eric miao <eric.miao@marvell.com>
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/pwm.h>
-#include <mach/hardware.h>
-
-
-/* i.MX1 and i.MX21 share the same PWM function block: */
-
-#define MX1_PWMC 0x00 /* PWM Control Register */
-#define MX1_PWMS 0x04 /* PWM Sample Register */
-#define MX1_PWMP 0x08 /* PWM Period Register */
-
-
-/* i.MX27, i.MX31, i.MX35 share the same PWM function block: */
-
-#define MX3_PWMCR 0x00 /* PWM Control Register */
-#define MX3_PWMSAR 0x0C /* PWM Sample Register */
-#define MX3_PWMPR 0x10 /* PWM Period Register */
-#define MX3_PWMCR_PRESCALER(x) (((x - 1) & 0xFFF) << 4)
-#define MX3_PWMCR_DOZEEN (1 << 24)
-#define MX3_PWMCR_WAITEN (1 << 23)
-#define MX3_PWMCR_DBGEN (1 << 22)
-#define MX3_PWMCR_CLKSRC_IPG_HIGH (2 << 16)
-#define MX3_PWMCR_CLKSRC_IPG (1 << 16)
-#define MX3_PWMCR_EN (1 << 0)
-
-
-
-struct pwm_device {
- struct list_head node;
- struct platform_device *pdev;
-
- const char *label;
- struct clk *clk;
-
- int clk_enabled;
- void __iomem *mmio_base;
-
- unsigned int use_count;
- unsigned int pwm_id;
-};
-
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
- if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
- return -EINVAL;
-
- if (!(cpu_is_mx1() || cpu_is_mx21())) {
- unsigned long long c;
- unsigned long period_cycles, duty_cycles, prescale;
- u32 cr;
-
- c = clk_get_rate(pwm->clk);
- c = c * period_ns;
- do_div(c, 1000000000);
- period_cycles = c;
-
- prescale = period_cycles / 0x10000 + 1;
-
- period_cycles /= prescale;
- c = (unsigned long long)period_cycles * duty_ns;
- do_div(c, period_ns);
- duty_cycles = c;
-
- /*
- * according to imx pwm RM, the real period value should be
- * PERIOD value in PWMPR plus 2.
- */
- if (period_cycles > 2)
- period_cycles -= 2;
- else
- period_cycles = 0;
-
- writel(duty_cycles, pwm->mmio_base + MX3_PWMSAR);
- writel(period_cycles, pwm->mmio_base + MX3_PWMPR);
-
- cr = MX3_PWMCR_PRESCALER(prescale) |
- MX3_PWMCR_DOZEEN | MX3_PWMCR_WAITEN |
- MX3_PWMCR_DBGEN | MX3_PWMCR_EN;
-
- if (cpu_is_mx25())
- cr |= MX3_PWMCR_CLKSRC_IPG;
- else
- cr |= MX3_PWMCR_CLKSRC_IPG_HIGH;
-
- writel(cr, pwm->mmio_base + MX3_PWMCR);
- } else if (cpu_is_mx1() || cpu_is_mx21()) {
- /* The PWM subsystem allows for exact frequencies. However,
- * I cannot connect a scope on my device to the PWM line and
- * thus cannot provide the program the PWM controller
- * exactly. Instead, I'm relying on the fact that the
- * Bootloader (u-boot or WinCE+haret) has programmed the PWM
- * function group already. So I'll just modify the PWM sample
- * register to follow the ratio of duty_ns vs. period_ns
- * accordingly.
- *
- * This is good enough for programming the brightness of
- * the LCD backlight.
- *
- * The real implementation would divide PERCLK[0] first by
- * both the prescaler (/1 .. /128) and then by CLKSEL
- * (/2 .. /16).
- */
- u32 max = readl(pwm->mmio_base + MX1_PWMP);
- u32 p = max * duty_ns / period_ns;
- writel(max - p, pwm->mmio_base + MX1_PWMS);
- } else {
- BUG();
- }
-
- return 0;
-}
-EXPORT_SYMBOL(pwm_config);
-
-int pwm_enable(struct pwm_device *pwm)
-{
- int rc = 0;
-
- if (!pwm->clk_enabled) {
- rc = clk_prepare_enable(pwm->clk);
- if (!rc)
- pwm->clk_enabled = 1;
- }
- return rc;
-}
-EXPORT_SYMBOL(pwm_enable);
-
-void pwm_disable(struct pwm_device *pwm)
-{
- writel(0, pwm->mmio_base + MX3_PWMCR);
-
- if (pwm->clk_enabled) {
- clk_disable_unprepare(pwm->clk);
- pwm->clk_enabled = 0;
- }
-}
-EXPORT_SYMBOL(pwm_disable);
-
-static DEFINE_MUTEX(pwm_lock);
-static LIST_HEAD(pwm_list);
-
-struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
- struct pwm_device *pwm;
- int found = 0;
-
- mutex_lock(&pwm_lock);
-
- list_for_each_entry(pwm, &pwm_list, node) {
- if (pwm->pwm_id == pwm_id) {
- found = 1;
- break;
- }
- }
-
- if (found) {
- if (pwm->use_count == 0) {
- pwm->use_count++;
- pwm->label = label;
- } else
- pwm = ERR_PTR(-EBUSY);
- } else
- pwm = ERR_PTR(-ENOENT);
-
- mutex_unlock(&pwm_lock);
- return pwm;
-}
-EXPORT_SYMBOL(pwm_request);
-
-void pwm_free(struct pwm_device *pwm)
-{
- mutex_lock(&pwm_lock);
-
- if (pwm->use_count) {
- pwm->use_count--;
- pwm->label = NULL;
- } else
- pr_warning("PWM device already freed\n");
-
- mutex_unlock(&pwm_lock);
-}
-EXPORT_SYMBOL(pwm_free);
-
-static int __devinit mxc_pwm_probe(struct platform_device *pdev)
-{
- struct pwm_device *pwm;
- struct resource *r;
- int ret = 0;
-
- pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
- if (pwm == NULL) {
- dev_err(&pdev->dev, "failed to allocate memory\n");
- return -ENOMEM;
- }
-
- pwm->clk = clk_get(&pdev->dev, "pwm");
-
- if (IS_ERR(pwm->clk)) {
- ret = PTR_ERR(pwm->clk);
- goto err_free;
- }
-
- pwm->clk_enabled = 0;
-
- pwm->use_count = 0;
- pwm->pwm_id = pdev->id;
- pwm->pdev = pdev;
-
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (r == NULL) {
- dev_err(&pdev->dev, "no memory resource defined\n");
- ret = -ENODEV;
- goto err_free_clk;
- }
-
- r = request_mem_region(r->start, resource_size(r), pdev->name);
- if (r == NULL) {
- dev_err(&pdev->dev, "failed to request memory resource\n");
- ret = -EBUSY;
- goto err_free_clk;
- }
-
- pwm->mmio_base = ioremap(r->start, resource_size(r));
- if (pwm->mmio_base == NULL) {
- dev_err(&pdev->dev, "failed to ioremap() registers\n");
- ret = -ENODEV;
- goto err_free_mem;
- }
-
- mutex_lock(&pwm_lock);
- list_add_tail(&pwm->node, &pwm_list);
- mutex_unlock(&pwm_lock);
-
- platform_set_drvdata(pdev, pwm);
- return 0;
-
-err_free_mem:
- release_mem_region(r->start, resource_size(r));
-err_free_clk:
- clk_put(pwm->clk);
-err_free:
- kfree(pwm);
- return ret;
-}
-
-static int __devexit mxc_pwm_remove(struct platform_device *pdev)
-{
- struct pwm_device *pwm;
- struct resource *r;
-
- pwm = platform_get_drvdata(pdev);
- if (pwm == NULL)
- return -ENODEV;
-
- mutex_lock(&pwm_lock);
- list_del(&pwm->node);
- mutex_unlock(&pwm_lock);
-
- iounmap(pwm->mmio_base);
-
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(r->start, resource_size(r));
-
- clk_put(pwm->clk);
-
- kfree(pwm);
- return 0;
-}
-
-static struct platform_driver mxc_pwm_driver = {
- .driver = {
- .name = "mxc_pwm",
- },
- .probe = mxc_pwm_probe,
- .remove = __devexit_p(mxc_pwm_remove),
-};
-
-static int __init mxc_pwm_init(void)
-{
- return platform_driver_register(&mxc_pwm_driver);
-}
-arch_initcall(mxc_pwm_init);
-
-static void __exit mxc_pwm_exit(void)
-{
- platform_driver_unregister(&mxc_pwm_driver);
-}
-module_exit(mxc_pwm_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de>");
diff --git a/arch/arm/plat-nomadik/include/plat/i2c.h b/arch/arm/plat-nomadik/include/plat/i2c.h
deleted file mode 100644
index 8ba70ffc31e..00000000000
--- a/arch/arm/plat-nomadik/include/plat/i2c.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright (C) 2009 ST-Ericsson
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2, as
- * published by the Free Software Foundation.
- */
-#ifndef __PLAT_I2C_H
-#define __PLAT_I2C_H
-
-enum i2c_freq_mode {
- I2C_FREQ_MODE_STANDARD, /* up to 100 Kb/s */
- I2C_FREQ_MODE_FAST, /* up to 400 Kb/s */
- I2C_FREQ_MODE_HIGH_SPEED, /* up to 3.4 Mb/s */
- I2C_FREQ_MODE_FAST_PLUS, /* up to 1 Mb/s */
-};
-
-/**
- * struct nmk_i2c_controller - client specific controller configuration
- * @clk_freq: clock frequency for the operation mode
- * @slsu: Slave data setup time in ns.
- * The needed setup time for three modes of operation
- * are 250ns, 100ns and 10ns respectively thus leading
- * to the values of 14, 6, 2 for a 48 MHz i2c clk
- * @tft: Tx FIFO Threshold in bytes
- * @rft: Rx FIFO Threshold in bytes
- * @timeout Slave response timeout(ms)
- * @sm: speed mode
- */
-struct nmk_i2c_controller {
- unsigned long clk_freq;
- unsigned short slsu;
- unsigned char tft;
- unsigned char rft;
- int timeout;
- enum i2c_freq_mode sm;
-};
-
-#endif /* __PLAT_I2C_H */
diff --git a/arch/arm/plat-omap/include/plat/mmc.h b/arch/arm/plat-omap/include/plat/mmc.h
index 5493bd95da5..eb3e4d55534 100644
--- a/arch/arm/plat-omap/include/plat/mmc.h
+++ b/arch/arm/plat-omap/include/plat/mmc.h
@@ -81,8 +81,6 @@ struct omap_mmc_platform_data {
/* Return context loss count due to PM states changing */
int (*get_context_loss_count)(struct device *dev);
- u64 dma_mask;
-
/* Integrating attributes from the omap_hwmod layer */
u8 controller_flags;
diff --git a/arch/arm/plat-pxa/Makefile b/arch/arm/plat-pxa/Makefile
index f302d048392..af8e484001e 100644
--- a/arch/arm/plat-pxa/Makefile
+++ b/arch/arm/plat-pxa/Makefile
@@ -8,5 +8,4 @@ obj-$(CONFIG_PXA3xx) += mfp.o
obj-$(CONFIG_PXA95x) += mfp.o
obj-$(CONFIG_ARCH_MMP) += mfp.o
-obj-$(CONFIG_HAVE_PWM) += pwm.o
obj-$(CONFIG_PXA_SSP) += ssp.o
diff --git a/arch/arm/plat-pxa/pwm.c b/arch/arm/plat-pxa/pwm.c
deleted file mode 100644
index ef32686feef..00000000000
--- a/arch/arm/plat-pxa/pwm.c
+++ /dev/null
@@ -1,304 +0,0 @@
-/*
- * linux/arch/arm/mach-pxa/pwm.c
- *
- * simple driver for PWM (Pulse Width Modulator) controller
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * 2008-02-13 initial version
- * eric miao <eric.miao@marvell.com>
- */
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/pwm.h>
-
-#include <asm/div64.h>
-
-#define HAS_SECONDARY_PWM 0x10
-#define PWM_ID_BASE(d) ((d) & 0xf)
-
-static const struct platform_device_id pwm_id_table[] = {
- /* PWM has_secondary_pwm? */
- { "pxa25x-pwm", 0 },
- { "pxa27x-pwm", 0 | HAS_SECONDARY_PWM },
- { "pxa168-pwm", 1 },
- { "pxa910-pwm", 1 },
- { },
-};
-MODULE_DEVICE_TABLE(platform, pwm_id_table);
-
-/* PWM registers and bits definitions */
-#define PWMCR (0x00)
-#define PWMDCR (0x04)
-#define PWMPCR (0x08)
-
-#define PWMCR_SD (1 << 6)
-#define PWMDCR_FD (1 << 10)
-
-struct pwm_device {
- struct list_head node;
- struct pwm_device *secondary;
- struct platform_device *pdev;
-
- const char *label;
- struct clk *clk;
- int clk_enabled;
- void __iomem *mmio_base;
-
- unsigned int use_count;
- unsigned int pwm_id;
-};
-
-/*
- * period_ns = 10^9 * (PRESCALE + 1) * (PV + 1) / PWM_CLK_RATE
- * duty_ns = 10^9 * (PRESCALE + 1) * DC / PWM_CLK_RATE
- */
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
- unsigned long long c;
- unsigned long period_cycles, prescale, pv, dc;
-
- if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
- return -EINVAL;
-
- c = clk_get_rate(pwm->clk);
- c = c * period_ns;
- do_div(c, 1000000000);
- period_cycles = c;
-
- if (period_cycles < 1)
- period_cycles = 1;
- prescale = (period_cycles - 1) / 1024;
- pv = period_cycles / (prescale + 1) - 1;
-
- if (prescale > 63)
- return -EINVAL;
-
- if (duty_ns == period_ns)
- dc = PWMDCR_FD;
- else
- dc = (pv + 1) * duty_ns / period_ns;
-
- /* NOTE: the clock to PWM has to be enabled first
- * before writing to the registers
- */
- clk_enable(pwm->clk);
- __raw_writel(prescale, pwm->mmio_base + PWMCR);
- __raw_writel(dc, pwm->mmio_base + PWMDCR);
- __raw_writel(pv, pwm->mmio_base + PWMPCR);
- clk_disable(pwm->clk);
-
- return 0;
-}
-EXPORT_SYMBOL(pwm_config);
-
-int pwm_enable(struct pwm_device *pwm)
-{
- int rc = 0;
-
- if (!pwm->clk_enabled) {
- rc = clk_enable(pwm->clk);
- if (!rc)
- pwm->clk_enabled = 1;
- }
- return rc;
-}
-EXPORT_SYMBOL(pwm_enable);
-
-void pwm_disable(struct pwm_device *pwm)
-{
- if (pwm->clk_enabled) {
- clk_disable(pwm->clk);
- pwm->clk_enabled = 0;
- }
-}
-EXPORT_SYMBOL(pwm_disable);
-
-static DEFINE_MUTEX(pwm_lock);
-static LIST_HEAD(pwm_list);
-
-struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
- struct pwm_device *pwm;
- int found = 0;
-
- mutex_lock(&pwm_lock);
-
- list_for_each_entry(pwm, &pwm_list, node) {
- if (pwm->pwm_id == pwm_id) {
- found = 1;
- break;
- }
- }
-
- if (found) {
- if (pwm->use_count == 0) {
- pwm->use_count++;
- pwm->label = label;
- } else
- pwm = ERR_PTR(-EBUSY);
- } else
- pwm = ERR_PTR(-ENOENT);
-
- mutex_unlock(&pwm_lock);
- return pwm;
-}
-EXPORT_SYMBOL(pwm_request);
-
-void pwm_free(struct pwm_device *pwm)
-{
- mutex_lock(&pwm_lock);
-
- if (pwm->use_count) {
- pwm->use_count--;
- pwm->label = NULL;
- } else
- pr_warning("PWM device already freed\n");
-
- mutex_unlock(&pwm_lock);
-}
-EXPORT_SYMBOL(pwm_free);
-
-static inline void __add_pwm(struct pwm_device *pwm)
-{
- mutex_lock(&pwm_lock);
- list_add_tail(&pwm->node, &pwm_list);
- mutex_unlock(&pwm_lock);
-}
-
-static int __devinit pwm_probe(struct platform_device *pdev)
-{
- const struct platform_device_id *id = platform_get_device_id(pdev);
- struct pwm_device *pwm, *secondary = NULL;
- struct resource *r;
- int ret = 0;
-
- pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
- if (pwm == NULL) {
- dev_err(&pdev->dev, "failed to allocate memory\n");
- return -ENOMEM;
- }
-
- pwm->clk = clk_get(&pdev->dev, NULL);
- if (IS_ERR(pwm->clk)) {
- ret = PTR_ERR(pwm->clk);
- goto err_free;
- }
- pwm->clk_enabled = 0;
-
- pwm->use_count = 0;
- pwm->pwm_id = PWM_ID_BASE(id->driver_data) + pdev->id;
- pwm->pdev = pdev;
-
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (r == NULL) {
- dev_err(&pdev->dev, "no memory resource defined\n");
- ret = -ENODEV;
- goto err_free_clk;
- }
-
- r = request_mem_region(r->start, resource_size(r), pdev->name);
- if (r == NULL) {
- dev_err(&pdev->dev, "failed to request memory resource\n");
- ret = -EBUSY;
- goto err_free_clk;
- }
-
- pwm->mmio_base = ioremap(r->start, resource_size(r));
- if (pwm->mmio_base == NULL) {
- dev_err(&pdev->dev, "failed to ioremap() registers\n");
- ret = -ENODEV;
- goto err_free_mem;
- }
-
- if (id->driver_data & HAS_SECONDARY_PWM) {
- secondary = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
- if (secondary == NULL) {
- ret = -ENOMEM;
- goto err_free_mem;
- }
-
- *secondary = *pwm;
- pwm->secondary = secondary;
-
- /* registers for the second PWM has offset of 0x10 */
- secondary->mmio_base = pwm->mmio_base + 0x10;
- secondary->pwm_id = pdev->id + 2;
- }
-
- __add_pwm(pwm);
- if (secondary)
- __add_pwm(secondary);
-
- platform_set_drvdata(pdev, pwm);
- return 0;
-
-err_free_mem:
- release_mem_region(r->start, resource_size(r));
-err_free_clk:
- clk_put(pwm->clk);
-err_free:
- kfree(pwm);
- return ret;
-}
-
-static int __devexit pwm_remove(struct platform_device *pdev)
-{
- struct pwm_device *pwm;
- struct resource *r;
-
- pwm = platform_get_drvdata(pdev);
- if (pwm == NULL)
- return -ENODEV;
-
- mutex_lock(&pwm_lock);
-
- if (pwm->secondary) {
- list_del(&pwm->secondary->node);
- kfree(pwm->secondary);
- }
-
- list_del(&pwm->node);
- mutex_unlock(&pwm_lock);
-
- iounmap(pwm->mmio_base);
-
- r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- release_mem_region(r->start, resource_size(r));
-
- clk_put(pwm->clk);
- kfree(pwm);
- return 0;
-}
-
-static struct platform_driver pwm_driver = {
- .driver = {
- .name = "pxa25x-pwm",
- .owner = THIS_MODULE,
- },
- .probe = pwm_probe,
- .remove = __devexit_p(pwm_remove),
- .id_table = pwm_id_table,
-};
-
-static int __init pwm_init(void)
-{
- return platform_driver_register(&pwm_driver);
-}
-arch_initcall(pwm_init);
-
-static void __exit pwm_exit(void)
-{
- platform_driver_unregister(&pwm_driver);
-}
-module_exit(pwm_exit);
-
-MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index b7871749667..9e40e8d0074 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -59,7 +59,3 @@ obj-$(CONFIG_SAMSUNG_WAKEMASK) += wakeup-mask.o
obj-$(CONFIG_S5P_PM) += s5p-pm.o s5p-irq-pm.o
obj-$(CONFIG_S5P_SLEEP) += s5p-sleep.o
-
-# PWM support
-
-obj-$(CONFIG_HAVE_PWM) += pwm.o
diff --git a/arch/arm/plat-samsung/pwm.c b/arch/arm/plat-samsung/pwm.c
deleted file mode 100644
index d3583050fb0..00000000000
--- a/arch/arm/plat-samsung/pwm.c
+++ /dev/null
@@ -1,416 +0,0 @@
-/* arch/arm/plat-s3c/pwm.c
- *
- * Copyright (c) 2007 Ben Dooks
- * Copyright (c) 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>, <ben-linux@fluff.org>
- *
- * S3C series PWM device core
- *
- * This program is free software; you can redistribute 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.
-*/
-
-#include <linux/export.h>
-#include <linux/kernel.h>
-#include <linux/platform_device.h>
-#include <linux/slab.h>
-#include <linux/err.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-#include <linux/pwm.h>
-
-#include <mach/map.h>
-
-#include <plat/regs-timer.h>
-
-struct pwm_device {
- struct list_head list;
- struct platform_device *pdev;
-
- struct clk *clk_div;
- struct clk *clk;
- const char *label;
-
- unsigned int period_ns;
- unsigned int duty_ns;
-
- unsigned char tcon_base;
- unsigned char use_count;
- unsigned char pwm_id;
-};
-
-#define pwm_dbg(_pwm, msg...) dev_dbg(&(_pwm)->pdev->dev, msg)
-
-static struct clk *clk_scaler[2];
-
-static inline int pwm_is_tdiv(struct pwm_device *pwm)
-{
- return clk_get_parent(pwm->clk) == pwm->clk_div;
-}
-
-static DEFINE_MUTEX(pwm_lock);
-static LIST_HEAD(pwm_list);
-
-struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
- struct pwm_device *pwm;
- int found = 0;
-
- mutex_lock(&pwm_lock);
-
- list_for_each_entry(pwm, &pwm_list, list) {
- if (pwm->pwm_id == pwm_id) {
- found = 1;
- break;
- }
- }
-
- if (found) {
- if (pwm->use_count == 0) {
- pwm->use_count = 1;
- pwm->label = label;
- } else
- pwm = ERR_PTR(-EBUSY);
- } else
- pwm = ERR_PTR(-ENOENT);
-
- mutex_unlock(&pwm_lock);
- return pwm;
-}
-
-EXPORT_SYMBOL(pwm_request);
-
-
-void pwm_free(struct pwm_device *pwm)
-{
- mutex_lock(&pwm_lock);
-
- if (pwm->use_count) {
- pwm->use_count--;
- pwm->label = NULL;
- } else
- printk(KERN_ERR "PWM%d device already freed\n", pwm->pwm_id);
-
- mutex_unlock(&pwm_lock);
-}
-
-EXPORT_SYMBOL(pwm_free);
-
-#define pwm_tcon_start(pwm) (1 << (pwm->tcon_base + 0))
-#define pwm_tcon_invert(pwm) (1 << (pwm->tcon_base + 2))
-#define pwm_tcon_autoreload(pwm) (1 << (pwm->tcon_base + 3))
-#define pwm_tcon_manulupdate(pwm) (1 << (pwm->tcon_base + 1))
-
-int pwm_enable(struct pwm_device *pwm)
-{
- unsigned long flags;
- unsigned long tcon;
-
- local_irq_save(flags);
-
- tcon = __raw_readl(S3C2410_TCON);
- tcon |= pwm_tcon_start(pwm);
- __raw_writel(tcon, S3C2410_TCON);
-
- local_irq_restore(flags);
-
- return 0;
-}
-
-EXPORT_SYMBOL(pwm_enable);
-
-void pwm_disable(struct pwm_device *pwm)
-{
- unsigned long flags;
- unsigned long tcon;
-
- local_irq_save(flags);
-
- tcon = __raw_readl(S3C2410_TCON);
- tcon &= ~pwm_tcon_start(pwm);
- __raw_writel(tcon, S3C2410_TCON);
-
- local_irq_restore(flags);
-}
-
-EXPORT_SYMBOL(pwm_disable);
-
-static unsigned long pwm_calc_tin(struct pwm_device *pwm, unsigned long freq)
-{
- unsigned long tin_parent_rate;
- unsigned int div;
-
- tin_parent_rate = clk_get_rate(clk_get_parent(pwm->clk_div));
- pwm_dbg(pwm, "tin parent at %lu\n", tin_parent_rate);
-
- for (div = 2; div <= 16; div *= 2) {
- if ((tin_parent_rate / (div << 16)) < freq)
- return tin_parent_rate / div;
- }
-
- return tin_parent_rate / 16;
-}
-
-#define NS_IN_HZ (1000000000UL)
-
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
- unsigned long tin_rate;
- unsigned long tin_ns;
- unsigned long period;
- unsigned long flags;
- unsigned long tcon;
- unsigned long tcnt;
- long tcmp;
-
- /* We currently avoid using 64bit arithmetic by using the
- * fact that anything faster than 1Hz is easily representable
- * by 32bits. */
-
- if (period_ns > NS_IN_HZ || duty_ns > NS_IN_HZ)
- return -ERANGE;
-
- if (duty_ns > period_ns)
- return -EINVAL;
-
- if (period_ns == pwm->period_ns &&
- duty_ns == pwm->duty_ns)
- return 0;
-
- /* The TCMP and TCNT can be read without a lock, they're not
- * shared between the timers. */
-
- tcmp = __raw_readl(S3C2410_TCMPB(pwm->pwm_id));
- tcnt = __raw_readl(S3C2410_TCNTB(pwm->pwm_id));
-
- period = NS_IN_HZ / period_ns;
-
- pwm_dbg(pwm, "duty_ns=%d, period_ns=%d (%lu)\n",
- duty_ns, period_ns, period);
-
- /* Check to see if we are changing the clock rate of the PWM */
-
- if (pwm->period_ns != period_ns) {
- if (pwm_is_tdiv(pwm)) {
- tin_rate = pwm_calc_tin(pwm, period);
- clk_set_rate(pwm->clk_div, tin_rate);
- } else
- tin_rate = clk_get_rate(pwm->clk);
-
- pwm->period_ns = period_ns;
-
- pwm_dbg(pwm, "tin_rate=%lu\n", tin_rate);
-
- tin_ns = NS_IN_HZ / tin_rate;
- tcnt = period_ns / tin_ns;
- } else
- tin_ns = NS_IN_HZ / clk_get_rate(pwm->clk);
-
- /* Note, counters count down */
-
- tcmp = duty_ns / tin_ns;
- tcmp = tcnt - tcmp;
- /* the pwm hw only checks the compare register after a decrement,
- so the pin never toggles if tcmp = tcnt */
- if (tcmp == tcnt)
- tcmp--;
-
- pwm_dbg(pwm, "tin_ns=%lu, tcmp=%ld/%lu\n", tin_ns, tcmp, tcnt);
-
- if (tcmp < 0)
- tcmp = 0;
-
- /* Update the PWM register block. */
-
- local_irq_save(flags);
-
- __raw_writel(tcmp, S3C2410_TCMPB(pwm->pwm_id));
- __raw_writel(tcnt, S3C2410_TCNTB(pwm->pwm_id));
-
- tcon = __raw_readl(S3C2410_TCON);
- tcon |= pwm_tcon_manulupdate(pwm);
- tcon |= pwm_tcon_autoreload(pwm);
- __raw_writel(tcon, S3C2410_TCON);
-
- tcon &= ~pwm_tcon_manulupdate(pwm);
- __raw_writel(tcon, S3C2410_TCON);
-
- local_irq_restore(flags);
-
- return 0;
-}
-
-EXPORT_SYMBOL(pwm_config);
-
-static int pwm_register(struct pwm_device *pwm)
-{
- pwm->duty_ns = -1;
- pwm->period_ns = -1;
-
- mutex_lock(&pwm_lock);
- list_add_tail(&pwm->list, &pwm_list);
- mutex_unlock(&pwm_lock);
-
- return 0;
-}
-
-static int s3c_pwm_probe(struct platform_device *pdev)
-{
- struct device *dev = &pdev->dev;
- struct pwm_device *pwm;
- unsigned long flags;
- unsigned long tcon;
- unsigned int id = pdev->id;
- int ret;
-
- if (id == 4) {
- dev_err(dev, "TIMER4 is currently not supported\n");
- return -ENXIO;
- }
-
- pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
- if (pwm == NULL) {
- dev_err(dev, "failed to allocate pwm_device\n");
- return -ENOMEM;
- }
-
- pwm->pdev = pdev;
- pwm->pwm_id = id;
-
- /* calculate base of control bits in TCON */
- pwm->tcon_base = id == 0 ? 0 : (id * 4) + 4;
-
- pwm->clk = clk_get(dev, "pwm-tin");
- if (IS_ERR(pwm->clk)) {
- dev_err(dev, "failed to get pwm tin clk\n");
- ret = PTR_ERR(pwm->clk);
- goto err_alloc;
- }
-
- pwm->clk_div = clk_get(dev, "pwm-tdiv");
- if (IS_ERR(pwm->clk_div)) {
- dev_err(dev, "failed to get pwm tdiv clk\n");
- ret = PTR_ERR(pwm->clk_div);
- goto err_clk_tin;
- }
-
- clk_enable(pwm->clk);
- clk_enable(pwm->clk_div);
-
- local_irq_save(flags);
-
- tcon = __raw_readl(S3C2410_TCON);
- tcon |= pwm_tcon_invert(pwm);
- __raw_writel(tcon, S3C2410_TCON);
-
- local_irq_restore(flags);
-
-
- ret = pwm_register(pwm);
- if (ret) {
- dev_err(dev, "failed to register pwm\n");
- goto err_clk_tdiv;
- }
-
- pwm_dbg(pwm, "config bits %02x\n",
- (__raw_readl(S3C2410_TCON) >> pwm->tcon_base) & 0x0f);
-
- dev_info(dev, "tin at %lu, tdiv at %lu, tin=%sclk, base %d\n",
- clk_get_rate(pwm->clk),
- clk_get_rate(pwm->clk_div),
- pwm_is_tdiv(pwm) ? "div" : "ext", pwm->tcon_base);
-
- platform_set_drvdata(pdev, pwm);
- return 0;
-
- err_clk_tdiv:
- clk_disable(pwm->clk_div);
- clk_disable(pwm->clk);
- clk_put(pwm->clk_div);
-
- err_clk_tin:
- clk_put(pwm->clk);
-
- err_alloc:
- kfree(pwm);
- return ret;
-}
-
-static int __devexit s3c_pwm_remove(struct platform_device *pdev)
-{
- struct pwm_device *pwm = platform_get_drvdata(pdev);
-
- clk_disable(pwm->clk_div);
- clk_disable(pwm->clk);
- clk_put(pwm->clk_div);
- clk_put(pwm->clk);
- kfree(pwm);
-
- return 0;
-}
-
-#ifdef CONFIG_PM
-static int s3c_pwm_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct pwm_device *pwm = platform_get_drvdata(pdev);
-
- /* No one preserve these values during suspend so reset them
- * Otherwise driver leaves PWM unconfigured if same values
- * passed to pwm_config
- */
- pwm->period_ns = 0;
- pwm->duty_ns = 0;
-
- return 0;
-}
-
-static int s3c_pwm_resume(struct platform_device *pdev)
-{
- struct pwm_device *pwm = platform_get_drvdata(pdev);
- unsigned long tcon;
-
- /* Restore invertion */
- tcon = __raw_readl(S3C2410_TCON);
- tcon |= pwm_tcon_invert(pwm);
- __raw_writel(tcon, S3C2410_TCON);
-
- return 0;
-}
-
-#else
-#define s3c_pwm_suspend NULL
-#define s3c_pwm_resume NULL
-#endif
-
-static struct platform_driver s3c_pwm_driver = {
- .driver = {
- .name = "s3c24xx-pwm",
- .owner = THIS_MODULE,
- },
- .probe = s3c_pwm_probe,
- .remove = __devexit_p(s3c_pwm_remove),
- .suspend = s3c_pwm_suspend,
- .resume = s3c_pwm_resume,
-};
-
-static int __init pwm_init(void)
-{
- int ret;
-
- clk_scaler[0] = clk_get(NULL, "pwm-scaler0");
- clk_scaler[1] = clk_get(NULL, "pwm-scaler1");
-
- if (IS_ERR(clk_scaler[0]) || IS_ERR(clk_scaler[1])) {
- printk(KERN_ERR "%s: failed to get scaler clocks\n", __func__);
- return -EINVAL;
- }
-
- ret = platform_driver_register(&s3c_pwm_driver);
- if (ret)
- printk(KERN_ERR "%s: failed to add pwm driver\n", __func__);
-
- return ret;
-}
-
-arch_initcall(pwm_init);
diff --git a/arch/arm/plat-spear/include/plat/pl080.h b/arch/arm/plat-spear/include/plat/pl080.h
index 2bc6b54460a..eb6590ded40 100644
--- a/arch/arm/plat-spear/include/plat/pl080.h
+++ b/arch/arm/plat-spear/include/plat/pl080.h
@@ -14,8 +14,8 @@
#ifndef __PLAT_PL080_H
#define __PLAT_PL080_H
-struct pl08x_dma_chan;
-int pl080_get_signal(struct pl08x_dma_chan *ch);
-void pl080_put_signal(struct pl08x_dma_chan *ch);
+struct pl08x_channel_data;
+int pl080_get_signal(const struct pl08x_channel_data *cd);
+void pl080_put_signal(const struct pl08x_channel_data *cd, int signal);
#endif /* __PLAT_PL080_H */
diff --git a/arch/arm/plat-spear/pl080.c b/arch/arm/plat-spear/pl080.c
index 12cf27f935f..cfa1199d0f4 100644
--- a/arch/arm/plat-spear/pl080.c
+++ b/arch/arm/plat-spear/pl080.c
@@ -27,9 +27,8 @@ struct {
unsigned char val;
} signals[16] = {{0, 0}, };
-int pl080_get_signal(struct pl08x_dma_chan *ch)
+int pl080_get_signal(const struct pl08x_channel_data *cd)
{
- const struct pl08x_channel_data *cd = ch->cd;
unsigned int signal = cd->min_signal, val;
unsigned long flags;
@@ -63,18 +62,17 @@ int pl080_get_signal(struct pl08x_dma_chan *ch)
return signal;
}
-void pl080_put_signal(struct pl08x_dma_chan *ch)
+void pl080_put_signal(const struct pl08x_channel_data *cd, int signal)
{
- const struct pl08x_channel_data *cd = ch->cd;
unsigned long flags;
spin_lock_irqsave(&lock, flags);
/* if signal is not used */
- if (!signals[cd->min_signal].busy)
+ if (!signals[signal].busy)
BUG();
- signals[cd->min_signal].busy--;
+ signals[signal].busy--;
spin_unlock_irqrestore(&lock, flags);
}
diff --git a/arch/arm/vfp/entry.S b/arch/arm/vfp/entry.S
index 4fa9903b83c..cc926c98598 100644
--- a/arch/arm/vfp/entry.S
+++ b/arch/arm/vfp/entry.S
@@ -7,18 +7,20 @@
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
- *
- * Basic entry code, called from the kernel's undefined instruction trap.
- * r0 = faulted instruction
- * r5 = faulted PC+4
- * r9 = successful return
- * r10 = thread_info structure
- * lr = failure return
*/
#include <asm/thread_info.h>
#include <asm/vfpmacros.h>
#include "../kernel/entry-header.S"
+@ VFP entry point.
+@
+@ r0 = instruction opcode (32-bit ARM or two 16-bit Thumb)
+@ r2 = PC value to resume execution after successful emulation
+@ r9 = normal "successful" return address
+@ r10 = this threads thread_info structure
+@ lr = unrecognised instruction return address
+@ IRQs disabled.
+@
ENTRY(do_vfp)
#ifdef CONFIG_PREEMPT
ldr r4, [r10, #TI_PREEMPT] @ get preempt count
diff --git a/arch/arm/vfp/vfphw.S b/arch/arm/vfp/vfphw.S
index 2d30c7f6edd..ea0349f6358 100644
--- a/arch/arm/vfp/vfphw.S
+++ b/arch/arm/vfp/vfphw.S
@@ -16,6 +16,7 @@
*/
#include <asm/thread_info.h>
#include <asm/vfpmacros.h>
+#include <linux/kern_levels.h>
#include "../kernel/entry-header.S"
.macro DBGSTR, str
@@ -24,7 +25,7 @@
add r0, pc, #4
bl printk
b 1f
- .asciz "<7>VFP: \str\n"
+ .asciz KERN_DEBUG "VFP: \str\n"
.balign 4
1: ldmfd sp!, {r0-r3, ip, lr}
#endif
@@ -37,7 +38,7 @@
add r0, pc, #4
bl printk
b 1f
- .asciz "<7>VFP: \str\n"
+ .asciz KERN_DEBUG "VFP: \str\n"
.balign 4
1: ldmfd sp!, {r0-r3, ip, lr}
#endif
@@ -52,7 +53,7 @@
add r0, pc, #4
bl printk
b 1f
- .asciz "<7>VFP: \str\n"
+ .asciz KERN_DEBUG "VFP: \str\n"
.balign 4
1: ldmfd sp!, {r0-r3, ip, lr}
#endif
@@ -61,13 +62,13 @@
@ VFP hardware support entry point.
@
-@ r0 = faulted instruction
-@ r2 = faulted PC+4
-@ r9 = successful return
+@ r0 = instruction opcode (32-bit ARM or two 16-bit Thumb)
+@ r2 = PC value to resume execution after successful emulation
+@ r9 = normal "successful" return address
@ r10 = vfp_state union
@ r11 = CPU number
-@ lr = failure return
-
+@ lr = unrecognised instruction return address
+@ IRQs enabled.
ENTRY(vfp_support_entry)
DBGSTR3 "instr %08x pc %08x state %p", r0, r2, r10
@@ -161,9 +162,12 @@ vfp_hw_state_valid:
@ exception before retrying branch
@ out before setting an FPEXC that
@ stops us reading stuff
- VFPFMXR FPEXC, r1 @ restore FPEXC last
- sub r2, r2, #4
- str r2, [sp, #S_PC] @ retry the instruction
+ VFPFMXR FPEXC, r1 @ Restore FPEXC last
+ sub r2, r2, #4 @ Retry current instruction - if Thumb
+ str r2, [sp, #S_PC] @ mode it's two 16-bit instructions,
+ @ else it's one 32-bit instruction, so
+ @ always subtract 4 from the following
+ @ instruction address.
#ifdef CONFIG_PREEMPT
get_thread_info r10
ldr r4, [r10, #TI_PREEMPT] @ get preempt count
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c
index 586961929e9..fb849d044bd 100644
--- a/arch/arm/vfp/vfpmodule.c
+++ b/arch/arm/vfp/vfpmodule.c
@@ -457,10 +457,16 @@ static int vfp_pm_suspend(void)
/* disable, just in case */
fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
+ } else if (vfp_current_hw_state[ti->cpu]) {
+#ifndef CONFIG_SMP
+ fmxr(FPEXC, fpexc | FPEXC_EN);
+ vfp_save_state(vfp_current_hw_state[ti->cpu], fpexc);
+ fmxr(FPEXC, fpexc);
+#endif
}
/* clear any information we had about last context state */
- memset(vfp_current_hw_state, 0, sizeof(vfp_current_hw_state));
+ vfp_current_hw_state[ti->cpu] = NULL;
return 0;
}
diff --git a/arch/avr32/Kconfig b/arch/avr32/Kconfig
index 71d38c76726..5ade51c8a87 100644
--- a/arch/avr32/Kconfig
+++ b/arch/avr32/Kconfig
@@ -12,6 +12,7 @@ config AVR32
select HARDIRQS_SW_RESEND
select GENERIC_IRQ_SHOW
select ARCH_HAVE_CUSTOM_GPIO_H
+ select ARCH_WANT_IPC_PARSE_VERSION
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_CLOCKEVENTS
help
diff --git a/arch/avr32/boards/atstk1000/atstk1002.c b/arch/avr32/boards/atstk1000/atstk1002.c
index dc526332148..6c80aba7bf9 100644
--- a/arch/avr32/boards/atstk1000/atstk1002.c
+++ b/arch/avr32/boards/atstk1000/atstk1002.c
@@ -97,7 +97,7 @@ static struct atmel_nand_data atstk1006_nand_data __initdata = {
.enable_pin = GPIO_PIN_PB(29),
.ecc_mode = NAND_ECC_SOFT,
.parts = nand_partitions,
- .num_parts = ARRAY_SIZE(num_partitions),
+ .num_parts = ARRAY_SIZE(nand_partitions),
};
#endif
diff --git a/arch/avr32/include/asm/unistd.h b/arch/avr32/include/asm/unistd.h
index f714544e556..1358e366f4b 100644
--- a/arch/avr32/include/asm/unistd.h
+++ b/arch/avr32/include/asm/unistd.h
@@ -318,7 +318,6 @@
/* SMP stuff */
#define __IGNORE_getcpu
-#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
index f7040a1e399..b92e6095861 100644
--- a/arch/avr32/mm/fault.c
+++ b/arch/avr32/mm/fault.c
@@ -61,10 +61,10 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
const struct exception_table_entry *fixup;
unsigned long address;
unsigned long page;
- int writeaccess;
long signr;
int code;
int fault;
+ unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
if (notify_page_fault(regs, ecr))
return;
@@ -86,6 +86,7 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
local_irq_enable();
+retry:
down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
@@ -104,7 +105,6 @@ asmlinkage void do_page_fault(unsigned long ecr, struct pt_regs *regs)
*/
good_area:
code = SEGV_ACCERR;
- writeaccess = 0;
switch (ecr) {
case ECR_PROTECTION_X:
@@ -121,7 +121,7 @@ good_area:
case ECR_TLB_MISS_W:
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
- writeaccess = 1;
+ flags |= FAULT_FLAG_WRITE;
break;
default:
panic("Unhandled case %lu in do_page_fault!", ecr);
@@ -132,7 +132,11 @@ good_area:
* sure we exit gracefully rather than endlessly redo the
* fault.
*/
- fault = handle_mm_fault(mm, vma, address, writeaccess ? FAULT_FLAG_WRITE : 0);
+ fault = handle_mm_fault(mm, vma, address, flags);
+
+ if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+ return;
+
if (unlikely(fault & VM_FAULT_ERROR)) {
if (fault & VM_FAULT_OOM)
goto out_of_memory;
@@ -140,10 +144,23 @@ good_area:
goto do_sigbus;
BUG();
}
- if (fault & VM_FAULT_MAJOR)
- tsk->maj_flt++;
- else
- tsk->min_flt++;
+
+ if (flags & FAULT_FLAG_ALLOW_RETRY) {
+ if (fault & VM_FAULT_MAJOR)
+ tsk->maj_flt++;
+ else
+ tsk->min_flt++;
+ if (fault & VM_FAULT_RETRY) {
+ flags &= ~FAULT_FLAG_ALLOW_RETRY;
+
+ /*
+ * No need to up_read(&mm->mmap_sem) as we would have
+ * already released it in __lock_page_or_retry() in
+ * mm/filemap.c.
+ */
+ goto retry;
+ }
+ }
up_read(&mm->mmap_sem);
return;
diff --git a/arch/blackfin/Kconfig b/arch/blackfin/Kconfig
index 9b765107e15..f3486192063 100644
--- a/arch/blackfin/Kconfig
+++ b/arch/blackfin/Kconfig
@@ -33,6 +33,7 @@ config BLACKFIN
select HAVE_PERF_EVENTS
select ARCH_HAVE_CUSTOM_GPIO_H
select ARCH_WANT_OPTIONAL_GPIOLIB
+ select ARCH_WANT_IPC_PARSE_VERSION
select HAVE_GENERIC_HARDIRQS
select GENERIC_ATOMIC64
select GENERIC_IRQ_PROBE
@@ -1002,16 +1003,6 @@ config BFIN_GPTIMERS
To compile this driver as a module, choose M here: the module
will be called gptimers.
-config HAVE_PWM
- tristate "Enable PWM API support"
- depends on BFIN_GPTIMERS
- help
- Enable support for the Pulse Width Modulation framework (as
- found in linux/pwm.h).
-
- To compile this driver as a module, choose M here: the module
- will be called pwm.
-
choice
prompt "Uncached DMA region"
default DMA_UNCACHED_1M
diff --git a/arch/blackfin/include/asm/unistd.h b/arch/blackfin/include/asm/unistd.h
index 3287222cba3..5b2a0748d7d 100644
--- a/arch/blackfin/include/asm/unistd.h
+++ b/arch/blackfin/include/asm/unistd.h
@@ -434,7 +434,6 @@
#define __IGNORE_getcpu
#ifdef __KERNEL__
-#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
diff --git a/arch/blackfin/kernel/Makefile b/arch/blackfin/kernel/Makefile
index 08e6625106b..735f24e0742 100644
--- a/arch/blackfin/kernel/Makefile
+++ b/arch/blackfin/kernel/Makefile
@@ -21,7 +21,6 @@ obj-$(CONFIG_FUNCTION_TRACER) += ftrace-entry.o
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o
CFLAGS_REMOVE_ftrace.o = -pg
-obj-$(CONFIG_HAVE_PWM) += pwm.o
obj-$(CONFIG_IPIPE) += ipipe.o
obj-$(CONFIG_BFIN_GPTIMERS) += gptimers.o
obj-$(CONFIG_CPLB_INFO) += cplbinfo.o
diff --git a/arch/blackfin/kernel/pwm.c b/arch/blackfin/kernel/pwm.c
deleted file mode 100644
index 33f5942733b..00000000000
--- a/arch/blackfin/kernel/pwm.c
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * Blackfin Pulse Width Modulation (PWM) core
- *
- * Copyright (c) 2011 Analog Devices Inc.
- *
- * Licensed under the GPL-2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/pwm.h>
-#include <linux/slab.h>
-
-#include <asm/gptimers.h>
-#include <asm/portmux.h>
-
-struct pwm_device {
- unsigned id;
- unsigned short pin;
-};
-
-static const unsigned short pwm_to_gptimer_per[] = {
- P_TMR0, P_TMR1, P_TMR2, P_TMR3, P_TMR4, P_TMR5,
- P_TMR6, P_TMR7, P_TMR8, P_TMR9, P_TMR10, P_TMR11,
-};
-
-struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
- struct pwm_device *pwm;
- int ret;
-
- /* XXX: pwm_id really should be unsigned */
- if (pwm_id < 0)
- return NULL;
-
- pwm = kzalloc(sizeof(*pwm), GFP_KERNEL);
- if (!pwm)
- return pwm;
-
- pwm->id = pwm_id;
- if (pwm->id >= ARRAY_SIZE(pwm_to_gptimer_per))
- goto err;
-
- pwm->pin = pwm_to_gptimer_per[pwm->id];
- ret = peripheral_request(pwm->pin, label);
- if (ret)
- goto err;
-
- return pwm;
- err:
- kfree(pwm);
- return NULL;
-}
-EXPORT_SYMBOL(pwm_request);
-
-void pwm_free(struct pwm_device *pwm)
-{
- peripheral_free(pwm->pin);
- kfree(pwm);
-}
-EXPORT_SYMBOL(pwm_free);
-
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
- unsigned long period, duty;
- unsigned long long val;
-
- if (duty_ns < 0 || duty_ns > period_ns)
- return -EINVAL;
-
- val = (unsigned long long)get_sclk() * period_ns;
- do_div(val, NSEC_PER_SEC);
- period = val;
-
- val = (unsigned long long)period * duty_ns;
- do_div(val, period_ns);
- duty = period - val;
-
- if (duty >= period)
- duty = period - 1;
-
- set_gptimer_config(pwm->id, TIMER_MODE_PWM | TIMER_PERIOD_CNT);
- set_gptimer_pwidth(pwm->id, duty);
- set_gptimer_period(pwm->id, period);
-
- return 0;
-}
-EXPORT_SYMBOL(pwm_config);
-
-int pwm_enable(struct pwm_device *pwm)
-{
- enable_gptimer(pwm->id);
- return 0;
-}
-EXPORT_SYMBOL(pwm_enable);
-
-void pwm_disable(struct pwm_device *pwm)
-{
- disable_gptimer(pwm->id);
-}
-EXPORT_SYMBOL(pwm_disable);
diff --git a/arch/cris/Kconfig b/arch/cris/Kconfig
index bb344650a14..e92215428a3 100644
--- a/arch/cris/Kconfig
+++ b/arch/cris/Kconfig
@@ -42,6 +42,7 @@ config CRIS
select HAVE_IDE
select GENERIC_ATOMIC64
select HAVE_GENERIC_HARDIRQS
+ select ARCH_WANT_IPC_PARSE_VERSION
select GENERIC_IRQ_SHOW
select GENERIC_IOMAP
select GENERIC_SMP_IDLE_THREAD if ETRAX_ARCH_V32
diff --git a/arch/cris/include/asm/unistd.h b/arch/cris/include/asm/unistd.h
index f921b8b0f97..51873a446f8 100644
--- a/arch/cris/include/asm/unistd.h
+++ b/arch/cris/include/asm/unistd.h
@@ -347,7 +347,6 @@
#include <arch/unistd.h>
-#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_OLD_STAT
#define __ARCH_WANT_STAT64
diff --git a/arch/frv/Kconfig b/arch/frv/Kconfig
index a685910d2d5..971c0a19fac 100644
--- a/arch/frv/Kconfig
+++ b/arch/frv/Kconfig
@@ -9,6 +9,7 @@ config FRV
select GENERIC_IRQ_SHOW
select ARCH_HAVE_NMI_SAFE_CMPXCHG
select GENERIC_CPU_DEVICES
+ select ARCH_WANT_IPC_PARSE_VERSION
config ZONE_DMA
bool
diff --git a/arch/frv/include/asm/cpumask.h b/arch/frv/include/asm/cpumask.h
deleted file mode 100644
index d999c20c84d..00000000000
--- a/arch/frv/include/asm/cpumask.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#ifndef _ASM_CPUMASK_H
-#define _ASM_CPUMASK_H
-
-#include <asm-generic/cpumask.h>
-
-#endif /* _ASM_CPUMASK_H */
diff --git a/arch/frv/include/asm/unistd.h b/arch/frv/include/asm/unistd.h
index a569dff7cd5..67f23a311db 100644
--- a/arch/frv/include/asm/unistd.h
+++ b/arch/frv/include/asm/unistd.h
@@ -349,7 +349,6 @@
#define NR_syscalls 338
-#define __ARCH_WANT_IPC_PARSE_VERSION
/* #define __ARCH_WANT_OLD_READDIR */
#define __ARCH_WANT_OLD_STAT
#define __ARCH_WANT_STAT64
diff --git a/arch/frv/kernel/kernel_thread.S b/arch/frv/kernel/kernel_thread.S
index 4531c830d20..f0e52943f92 100644
--- a/arch/frv/kernel/kernel_thread.S
+++ b/arch/frv/kernel/kernel_thread.S
@@ -10,10 +10,10 @@
*/
#include <linux/linkage.h>
+#include <linux/kern_levels.h>
#include <asm/unistd.h>
#define CLONE_VM 0x00000100 /* set if VM shared between processes */
-#define KERN_ERR "<3>"
.section .rodata
kernel_thread_emsg:
diff --git a/arch/h8300/Kconfig b/arch/h8300/Kconfig
index 56e890df505..5e8a0d9a09c 100644
--- a/arch/h8300/Kconfig
+++ b/arch/h8300/Kconfig
@@ -3,6 +3,7 @@ config H8300
default y
select HAVE_IDE
select HAVE_GENERIC_HARDIRQS
+ select ARCH_WANT_IPC_PARSE_VERSION
select GENERIC_IRQ_SHOW
select GENERIC_CPU_DEVICES
diff --git a/arch/h8300/include/asm/unistd.h b/arch/h8300/include/asm/unistd.h
index 718511303b4..5cd882801d7 100644
--- a/arch/h8300/include/asm/unistd.h
+++ b/arch/h8300/include/asm/unistd.h
@@ -331,7 +331,6 @@
#define NR_syscalls 321
-#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_OLD_STAT
#define __ARCH_WANT_STAT64
diff --git a/arch/hexagon/include/asm/Kbuild b/arch/hexagon/include/asm/Kbuild
index 9aa17f1917e..06906427c0a 100644
--- a/arch/hexagon/include/asm/Kbuild
+++ b/arch/hexagon/include/asm/Kbuild
@@ -7,7 +7,6 @@ header-y += user.h
generic-y += auxvec.h
generic-y += bug.h
generic-y += bugs.h
-generic-y += cpumask.h
generic-y += cputime.h
generic-y += current.h
generic-y += device.h
@@ -23,7 +22,6 @@ generic-y += ioctl.h
generic-y += ioctls.h
generic-y += iomap.h
generic-y += ipcbuf.h
-generic-y += ipc.h
generic-y += irq_regs.h
generic-y += kdebug.h
generic-y += kmap_types.h
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 8186ec5ea15..310cf5781fa 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -126,6 +126,7 @@ config AUDIT_ARCH
menuconfig PARAVIRT_GUEST
bool "Paravirtualized guest support"
+ depends on BROKEN
help
Say Y here to get to see options related to running Linux under
various hypervisors. This option alone does not add any kernel code.
@@ -138,8 +139,6 @@ config PARAVIRT
bool "Enable paravirtualization code"
depends on PARAVIRT_GUEST
default y
- bool
- default y
help
This changes the kernel so it can modify itself when it is run
under a hypervisor, potentially improving performance significantly
diff --git a/arch/ia64/include/asm/atomic.h b/arch/ia64/include/asm/atomic.h
index 7d9116600a3..6e6fe1839f5 100644
--- a/arch/ia64/include/asm/atomic.h
+++ b/arch/ia64/include/asm/atomic.h
@@ -17,8 +17,8 @@
#include <asm/intrinsics.h>
-#define ATOMIC_INIT(i) ((atomic_t) { (i) })
-#define ATOMIC64_INIT(i) ((atomic64_t) { (i) })
+#define ATOMIC_INIT(i) { (i) }
+#define ATOMIC64_INIT(i) { (i) }
#define atomic_read(v) (*(volatile int *)&(v)->counter)
#define atomic64_read(v) (*(volatile long *)&(v)->counter)
diff --git a/arch/ia64/include/asm/machvec.h b/arch/ia64/include/asm/machvec.h
index 367d299d993..2d1ad4b11a8 100644
--- a/arch/ia64/include/asm/machvec.h
+++ b/arch/ia64/include/asm/machvec.h
@@ -120,7 +120,7 @@ extern void machvec_tlb_migrate_finish (struct mm_struct *);
# ifdef MACHVEC_PLATFORM_HEADER
# include MACHVEC_PLATFORM_HEADER
# else
-# define platform_name ia64_mv.name
+# define ia64_platform_name ia64_mv.name
# define platform_setup ia64_mv.setup
# define platform_cpu_init ia64_mv.cpu_init
# define platform_irq_init ia64_mv.irq_init
diff --git a/arch/ia64/include/asm/machvec_dig.h b/arch/ia64/include/asm/machvec_dig.h
index 8a0752f4098..1f7403a2fbe 100644
--- a/arch/ia64/include/asm/machvec_dig.h
+++ b/arch/ia64/include/asm/machvec_dig.h
@@ -10,7 +10,7 @@ extern ia64_mv_setup_t dig_setup;
* platform's machvec structure. When compiling a non-generic kernel,
* the macros are used directly.
*/
-#define platform_name "dig"
+#define ia64_platform_name "dig"
#define platform_setup dig_setup
#endif /* _ASM_IA64_MACHVEC_DIG_h */
diff --git a/arch/ia64/include/asm/machvec_dig_vtd.h b/arch/ia64/include/asm/machvec_dig_vtd.h
index 6ab1de5c45e..44308b4c3f6 100644
--- a/arch/ia64/include/asm/machvec_dig_vtd.h
+++ b/arch/ia64/include/asm/machvec_dig_vtd.h
@@ -11,7 +11,7 @@ extern ia64_mv_dma_init pci_iommu_alloc;
* platform's machvec structure. When compiling a non-generic kernel,
* the macros are used directly.
*/
-#define platform_name "dig_vtd"
+#define ia64_platform_name "dig_vtd"
#define platform_setup dig_setup
#define platform_dma_init pci_iommu_alloc
diff --git a/arch/ia64/include/asm/machvec_hpsim.h b/arch/ia64/include/asm/machvec_hpsim.h
index cf72fc87fdf..e7571127936 100644
--- a/arch/ia64/include/asm/machvec_hpsim.h
+++ b/arch/ia64/include/asm/machvec_hpsim.h
@@ -11,7 +11,7 @@ extern ia64_mv_irq_init_t hpsim_irq_init;
* platform's machvec structure. When compiling a non-generic kernel,
* the macros are used directly.
*/
-#define platform_name "hpsim"
+#define ia64_platform_name "hpsim"
#define platform_setup hpsim_setup
#define platform_irq_init hpsim_irq_init
diff --git a/arch/ia64/include/asm/machvec_hpzx1.h b/arch/ia64/include/asm/machvec_hpzx1.h
index 3bd83d78a41..c74d3159e9e 100644
--- a/arch/ia64/include/asm/machvec_hpzx1.h
+++ b/arch/ia64/include/asm/machvec_hpzx1.h
@@ -11,7 +11,7 @@ extern ia64_mv_dma_init sba_dma_init;
* platform's machvec structure. When compiling a non-generic kernel,
* the macros are used directly.
*/
-#define platform_name "hpzx1"
+#define ia64_platform_name "hpzx1"
#define platform_setup dig_setup
#define platform_dma_init sba_dma_init
diff --git a/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h b/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h
index 1091ac39740..906ef621077 100644
--- a/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h
+++ b/arch/ia64/include/asm/machvec_hpzx1_swiotlb.h
@@ -11,7 +11,7 @@ extern ia64_mv_dma_get_ops hwsw_dma_get_ops;
* platform's machvec structure. When compiling a non-generic kernel,
* the macros are used directly.
*/
-#define platform_name "hpzx1_swiotlb"
+#define ia64_platform_name "hpzx1_swiotlb"
#define platform_setup dig_setup
#define platform_dma_init machvec_noop
#define platform_dma_get_ops hwsw_dma_get_ops
diff --git a/arch/ia64/include/asm/machvec_sn2.h b/arch/ia64/include/asm/machvec_sn2.h
index f061a30aac4..ece9fa85be8 100644
--- a/arch/ia64/include/asm/machvec_sn2.h
+++ b/arch/ia64/include/asm/machvec_sn2.h
@@ -71,7 +71,7 @@ extern ia64_mv_pci_fixup_bus_t sn_pci_fixup_bus;
* platform's machvec structure. When compiling a non-generic kernel,
* the macros are used directly.
*/
-#define platform_name "sn2"
+#define ia64_platform_name "sn2"
#define platform_setup sn_setup
#define platform_cpu_init sn_cpu_init
#define platform_irq_init sn_irq_init
diff --git a/arch/ia64/include/asm/machvec_uv.h b/arch/ia64/include/asm/machvec_uv.h
index 2931447f381..2c50853f35a 100644
--- a/arch/ia64/include/asm/machvec_uv.h
+++ b/arch/ia64/include/asm/machvec_uv.h
@@ -20,7 +20,7 @@ extern ia64_mv_setup_t uv_setup;
* platform's machvec structure. When compiling a non-generic kernel,
* the macros are used directly.
*/
-#define platform_name "uv"
+#define ia64_platform_name "uv"
#define platform_setup uv_setup
#endif /* _ASM_IA64_MACHVEC_UV_H */
diff --git a/arch/ia64/include/asm/machvec_xen.h b/arch/ia64/include/asm/machvec_xen.h
index 55f9228056c..8b8bd0eb392 100644
--- a/arch/ia64/include/asm/machvec_xen.h
+++ b/arch/ia64/include/asm/machvec_xen.h
@@ -13,7 +13,7 @@ extern ia64_mv_send_ipi_t xen_platform_send_ipi;
* platform's machvec structure. When compiling a non-generic kernel,
* the macros are used directly.
*/
-#define platform_name "xen"
+#define ia64_platform_name "xen"
#define platform_setup dig_setup
#define platform_cpu_init xen_cpu_init
#define platform_irq_init xen_irq_init
diff --git a/arch/ia64/include/asm/processor.h b/arch/ia64/include/asm/processor.h
index 832dd3789e9..944152a5091 100644
--- a/arch/ia64/include/asm/processor.h
+++ b/arch/ia64/include/asm/processor.h
@@ -719,7 +719,7 @@ enum idle_boot_override {IDLE_NO_OVERRIDE=0, IDLE_HALT, IDLE_FORCE_MWAIT,
void default_idle(void);
-#define ia64_platform_is(x) (strcmp(x, platform_name) == 0)
+#define ia64_platform_is(x) (strcmp(x, ia64_platform_name) == 0)
#endif /* !__ASSEMBLY__ */
diff --git a/arch/ia64/kernel/irq_ia64.c b/arch/ia64/kernel/irq_ia64.c
index 5c3e0888265..1034884b77d 100644
--- a/arch/ia64/kernel/irq_ia64.c
+++ b/arch/ia64/kernel/irq_ia64.c
@@ -23,7 +23,6 @@
#include <linux/ioport.h>
#include <linux/kernel_stat.h>
#include <linux/ptrace.h>
-#include <linux/random.h> /* for rand_initialize_irq() */
#include <linux/signal.h>
#include <linux/smp.h>
#include <linux/threads.h>
diff --git a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
index d7f558c1e71..3fa4bc53695 100644
--- a/arch/ia64/kernel/perfmon.c
+++ b/arch/ia64/kernel/perfmon.c
@@ -2353,7 +2353,6 @@ pfm_smpl_buffer_alloc(struct task_struct *task, struct file *filp, pfm_context_t
*/
insert_vm_struct(mm, vma);
- mm->total_vm += size >> PAGE_SHIFT;
vm_stat_account(vma->vm_mm, vma->vm_flags, vma->vm_file,
vma_pages(vma));
up_write(&task->mm->mmap_sem);
diff --git a/arch/ia64/kvm/Kconfig b/arch/ia64/kvm/Kconfig
index df5351e3eed..e7947528aee 100644
--- a/arch/ia64/kvm/Kconfig
+++ b/arch/ia64/kvm/Kconfig
@@ -23,6 +23,7 @@ config KVM
depends on HAVE_KVM && MODULES && EXPERIMENTAL
# for device assignment:
depends on PCI
+ depends on BROKEN
select PREEMPT_NOTIFIERS
select ANON_INODES
select HAVE_KVM_IRQCHIP
diff --git a/arch/ia64/pci/fixup.c b/arch/ia64/pci/fixup.c
index f5959c0c181..eab28e31402 100644
--- a/arch/ia64/pci/fixup.c
+++ b/arch/ia64/pci/fixup.c
@@ -30,8 +30,8 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev)
struct pci_bus *bus;
u16 config;
- if ((strcmp(platform_name, "dig") != 0)
- && (strcmp(platform_name, "hpzx1") != 0))
+ if ((strcmp(ia64_platform_name, "dig") != 0)
+ && (strcmp(ia64_platform_name, "hpzx1") != 0))
return;
/* Maybe, this machine supports legacy memory map. */
diff --git a/arch/m32r/Kconfig b/arch/m32r/Kconfig
index b638d5bfa14..49498bbb961 100644
--- a/arch/m32r/Kconfig
+++ b/arch/m32r/Kconfig
@@ -7,6 +7,7 @@ config M32R
select HAVE_KERNEL_GZIP
select HAVE_KERNEL_BZIP2
select HAVE_KERNEL_LZMA
+ select ARCH_WANT_IPC_PARSE_VERSION
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
diff --git a/arch/m32r/include/asm/unistd.h b/arch/m32r/include/asm/unistd.h
index 3e1db561aac..d5e66a48078 100644
--- a/arch/m32r/include/asm/unistd.h
+++ b/arch/m32r/include/asm/unistd.h
@@ -336,7 +336,6 @@
#define NR_syscalls 326
-#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig
index 14712012826..0b0f8b8c4a2 100644
--- a/arch/m68k/Kconfig
+++ b/arch/m68k/Kconfig
@@ -10,6 +10,7 @@ config M68K
select GENERIC_STRNCPY_FROM_USER if MMU
select GENERIC_STRNLEN_USER if MMU
select FPU if MMU
+ select ARCH_WANT_IPC_PARSE_VERSION
select ARCH_USES_GETTIMEOFFSET if MMU && !COLDFIRE
config RWSEM_GENERIC_SPINLOCK
diff --git a/arch/m68k/include/asm/unistd.h b/arch/m68k/include/asm/unistd.h
index ea0b502f845..045cfd6a9e3 100644
--- a/arch/m68k/include/asm/unistd.h
+++ b/arch/m68k/include/asm/unistd.h
@@ -357,7 +357,6 @@
#define NR_syscalls 347
-#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_OLD_STAT
#define __ARCH_WANT_STAT64
diff --git a/arch/microblaze/Kconfig b/arch/microblaze/Kconfig
index 0bf44231aaf..ab9afcaa7f6 100644
--- a/arch/microblaze/Kconfig
+++ b/arch/microblaze/Kconfig
@@ -15,6 +15,7 @@ config MICROBLAZE
select TRACING_SUPPORT
select OF
select OF_EARLY_FLATTREE
+ select ARCH_WANT_IPC_PARSE_VERSION
select IRQ_DOMAIN
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_PROBE
diff --git a/arch/microblaze/include/asm/unistd.h b/arch/microblaze/include/asm/unistd.h
index d20ffbc86be..6985e6e9d82 100644
--- a/arch/microblaze/include/asm/unistd.h
+++ b/arch/microblaze/include/asm/unistd.h
@@ -400,7 +400,6 @@
#ifdef __KERNEL__
#ifndef __ASSEMBLY__
-#define __ARCH_WANT_IPC_PARSE_VERSION
/* #define __ARCH_WANT_OLD_READDIR */
/* #define __ARCH_WANT_OLD_STAT */
#define __ARCH_WANT_STAT64
diff --git a/arch/mips/Kbuild.platforms b/arch/mips/Kbuild.platforms
index 5ce8029f558..d64786d5e2f 100644
--- a/arch/mips/Kbuild.platforms
+++ b/arch/mips/Kbuild.platforms
@@ -14,6 +14,7 @@ platforms += jz4740
platforms += lantiq
platforms += lasat
platforms += loongson
+platforms += loongson1
platforms += mipssim
platforms += mti-malta
platforms += netlogic
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index b3e10fdd389..331d574df99 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -20,12 +20,14 @@ config MIPS
select ARCH_BINFMT_ELF_RANDOMIZE_PIE
select RTC_LIB if !MACH_LOONGSON
select GENERIC_ATOMIC64 if !64BIT
+ select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select HAVE_DMA_ATTRS
select HAVE_DMA_API_DEBUG
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_PROBE
select GENERIC_IRQ_SHOW
select HAVE_ARCH_JUMP_LABEL
+ select ARCH_WANT_IPC_PARSE_VERSION
select IRQ_FORCED_THREADING
select HAVE_MEMBLOCK
select HAVE_MEMBLOCK_NODE_MAP
@@ -75,6 +77,7 @@ config AR7
select SYS_SUPPORTS_ZBOOT_UART16550
select ARCH_REQUIRE_GPIOLIB
select VLYNQ
+ select HAVE_CLK
help
Support for the Texas Instruments AR7 System-on-a-Chip
family: TNETD7100, 7200 and 7300.
@@ -122,6 +125,7 @@ config BCM63XX
select SYS_HAS_EARLY_PRINTK
select SWAP_IO_SPACE
select ARCH_REQUIRE_GPIOLIB
+ select HAVE_CLK
help
Support for BCM63XX based boards
@@ -209,6 +213,7 @@ config MACH_JZ4740
select SYS_HAS_CPU_MIPS32_R1
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_ZBOOT_UART16550
select DMA_NONCOHERENT
select IRQ_CPU
select GENERIC_GPIO
@@ -264,6 +269,16 @@ config MACH_LOONGSON
Chinese Academy of Sciences (CAS) in the People's Republic
of China. The chief architect is Professor Weiwu Hu.
+config MACH_LOONGSON1
+ bool "Loongson 1 family of machines"
+ select SYS_SUPPORTS_ZBOOT
+ help
+ This enables support for the Loongson 1 based machines.
+
+ Loongson 1 is a family of 32-bit MIPS-compatible SoCs developed by
+ the ICT (Institute of Computing Technology) and the Chinese Academy
+ of Sciences.
+
config MIPS_MALTA
bool "MIPS Malta board"
select ARCH_MAY_HAVE_PC_FDC
@@ -787,6 +802,8 @@ config NLM_XLR_BOARD
select ZONE_DMA if 64BIT
select SYNC_R4K
select SYS_HAS_EARLY_PRINTK
+ select USB_ARCH_HAS_OHCI if USB_SUPPORT
+ select USB_ARCH_HAS_EHCI if USB_SUPPORT
help
Support for systems based on Netlogic XLR and XLS processors.
Say Y here if you have a XLR or XLS based board.
@@ -799,7 +816,6 @@ config NLM_XLP_BOARD
select SYS_HAS_CPU_XLP
select SYS_SUPPORTS_SMP
select HW_HAS_PCI
- select SWAP_IO_SPACE
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_64BIT_KERNEL
select 64BIT_PHYS_ADDR
@@ -836,6 +852,7 @@ source "arch/mips/txx9/Kconfig"
source "arch/mips/vr41xx/Kconfig"
source "arch/mips/cavium-octeon/Kconfig"
source "arch/mips/loongson/Kconfig"
+source "arch/mips/loongson1/Kconfig"
source "arch/mips/netlogic/Kconfig"
endmenu
@@ -1217,6 +1234,14 @@ config CPU_LOONGSON2F
have a similar programming interface with FPGA northbridge used in
Loongson2E.
+config CPU_LOONGSON1B
+ bool "Loongson 1B"
+ depends on SYS_HAS_CPU_LOONGSON1B
+ select CPU_LOONGSON1
+ help
+ The Loongson 1B is a 32-bit SoC, which implements the MIPS32
+ release 2 instruction set.
+
config CPU_MIPS32_R1
bool "MIPS32 Release 1"
depends on SYS_HAS_CPU_MIPS32_R1
@@ -1432,6 +1457,8 @@ config CPU_CAVIUM_OCTEON
select WEAK_ORDERING
select CPU_SUPPORTS_HIGHMEM
select CPU_SUPPORTS_HUGEPAGES
+ select LIBFDT
+ select USE_OF
help
The Cavium Octeon processor is a highly integrated chip containing
many ethernet hardware widgets for networking tasks. The processor
@@ -1544,6 +1571,14 @@ config CPU_LOONGSON2
select CPU_SUPPORTS_64BIT_KERNEL
select CPU_SUPPORTS_HIGHMEM
+config CPU_LOONGSON1
+ bool
+ select CPU_MIPS32
+ select CPU_MIPSR2
+ select CPU_HAS_PREFETCH
+ select CPU_SUPPORTS_32BIT_KERNEL
+ select CPU_SUPPORTS_HIGHMEM
+
config CPU_BMIPS
bool
select CPU_MIPS32
@@ -1562,6 +1597,9 @@ config SYS_HAS_CPU_LOONGSON2F
select CPU_SUPPORTS_ADDRWINCFG if 64BIT
select CPU_SUPPORTS_UNCACHED_ACCELERATED
+config SYS_HAS_CPU_LOONGSON1B
+ bool
+
config SYS_HAS_CPU_MIPS32_R1
bool
@@ -2366,6 +2404,8 @@ config PCI_DOMAINS
source "drivers/pci/Kconfig"
+source "drivers/pci/pcie/Kconfig"
+
#
# ISA support is now enabled via select. Too many systems still have the one
# or other ISA chip on the board that users don't know about so don't expect
diff --git a/arch/mips/alchemy/board-mtx1.c b/arch/mips/alchemy/board-mtx1.c
index 295f1a95f74..99969484c47 100644
--- a/arch/mips/alchemy/board-mtx1.c
+++ b/arch/mips/alchemy/board-mtx1.c
@@ -81,10 +81,10 @@ static void mtx1_power_off(void)
void __init board_setup(void)
{
-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+#if IS_ENABLED(CONFIG_USB_OHCI_HCD)
/* Enable USB power switch */
alchemy_gpio_direction_output(204, 0);
-#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
+#endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */
/* Initialize sys_pinfunc */
au_writel(SYS_PF_NI2, SYS_PINFUNC);
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c
index 95cb9113b12..c0f3ce6dcb5 100644
--- a/arch/mips/alchemy/common/platform.c
+++ b/arch/mips/alchemy/common/platform.c
@@ -334,13 +334,12 @@ static void __init alchemy_setup_macs(int ctype)
if (alchemy_get_macs(ctype) < 1)
return;
- macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
+ macres = kmemdup(au1xxx_eth0_resources[ctype],
+ sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
if (!macres) {
printk(KERN_INFO "Alchemy: no memory for MAC0 resources\n");
return;
}
- memcpy(macres, au1xxx_eth0_resources[ctype],
- sizeof(struct resource) * MAC_RES_COUNT);
au1xxx_eth0_device.resource = macres;
i = prom_get_ethernet_addr(ethaddr);
@@ -356,13 +355,12 @@ static void __init alchemy_setup_macs(int ctype)
if (alchemy_get_macs(ctype) < 2)
return;
- macres = kmalloc(sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
+ macres = kmemdup(au1xxx_eth1_resources[ctype],
+ sizeof(struct resource) * MAC_RES_COUNT, GFP_KERNEL);
if (!macres) {
printk(KERN_INFO "Alchemy: no memory for MAC1 resources\n");
return;
}
- memcpy(macres, au1xxx_eth1_resources[ctype],
- sizeof(struct resource) * MAC_RES_COUNT);
au1xxx_eth1_device.resource = macres;
ethaddr[5] += 1; /* next addr for 2nd MAC */
diff --git a/arch/mips/alchemy/devboards/Makefile b/arch/mips/alchemy/devboards/Makefile
index 3c37fb30336..c9e747dd9fc 100644
--- a/arch/mips/alchemy/devboards/Makefile
+++ b/arch/mips/alchemy/devboards/Makefile
@@ -2,7 +2,7 @@
# Alchemy Develboards
#
-obj-y += prom.o bcsr.o platform.o
+obj-y += bcsr.o platform.o
obj-$(CONFIG_PM) += pm.o
obj-$(CONFIG_MIPS_PB1100) += pb1100.o
obj-$(CONFIG_MIPS_PB1500) += pb1500.o
diff --git a/arch/mips/alchemy/devboards/bcsr.c b/arch/mips/alchemy/devboards/bcsr.c
index 1e83ce2e114..f2039ef2c29 100644
--- a/arch/mips/alchemy/devboards/bcsr.c
+++ b/arch/mips/alchemy/devboards/bcsr.c
@@ -90,10 +90,7 @@ static void bcsr_csc_handler(unsigned int irq, struct irq_desc *d)
unsigned short bisr = __raw_readw(bcsr_virt + BCSR_REG_INTSTAT);
disable_irq_nosync(irq);
-
- for ( ; bisr; bisr &= bisr - 1)
- generic_handle_irq(bcsr_csc_base + __ffs(bisr));
-
+ generic_handle_irq(bcsr_csc_base + __ffs(bisr));
enable_irq(irq);
}
diff --git a/arch/mips/alchemy/devboards/pb1100.c b/arch/mips/alchemy/devboards/pb1100.c
index cff50d05ddd..78c77a44a31 100644
--- a/arch/mips/alchemy/devboards/pb1100.c
+++ b/arch/mips/alchemy/devboards/pb1100.c
@@ -46,7 +46,7 @@ void __init board_setup(void)
alchemy_gpio1_input_enable();
udelay(100);
-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+#if IS_ENABLED(CONFIG_USB_OHCI_HCD)
{
u32 pin_func, sys_freqctrl, sys_clksrc;
@@ -93,7 +93,7 @@ void __init board_setup(void)
pin_func |= SYS_PF_USB;
au_writel(pin_func, SYS_PINFUNC);
}
-#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
+#endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */
/* Enable sys bus clock divider when IDLE state or no bus activity. */
au_writel(au_readl(SYS_POWERCTRL) | (0x3 << 5), SYS_POWERCTRL);
diff --git a/arch/mips/alchemy/devboards/pb1500.c b/arch/mips/alchemy/devboards/pb1500.c
index e7b807b3ec5..232fee94200 100644
--- a/arch/mips/alchemy/devboards/pb1500.c
+++ b/arch/mips/alchemy/devboards/pb1500.c
@@ -53,7 +53,7 @@ void __init board_setup(void)
alchemy_gpio_direction_input(201);
alchemy_gpio_direction_input(203);
-#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
+#if IS_ENABLED(CONFIG_USB_OHCI_HCD)
/* Zero and disable FREQ2 */
sys_freqctrl = au_readl(SYS_FREQCTRL0);
@@ -87,7 +87,7 @@ void __init board_setup(void)
/* 2nd USB port is USB host */
pin_func |= SYS_PF_USB;
au_writel(pin_func, SYS_PINFUNC);
-#endif /* defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE) */
+#endif /* IS_ENABLED(CONFIG_USB_OHCI_HCD) */
#ifdef CONFIG_PCI
{
diff --git a/arch/mips/alchemy/devboards/platform.c b/arch/mips/alchemy/devboards/platform.c
index 621f70afb63..f39042e99d0 100644
--- a/arch/mips/alchemy/devboards/platform.c
+++ b/arch/mips/alchemy/devboards/platform.c
@@ -10,9 +10,39 @@
#include <linux/platform_device.h>
#include <linux/pm.h>
+#include <asm/bootinfo.h>
#include <asm/reboot.h>
+#include <asm/mach-au1x00/au1000.h>
#include <asm/mach-db1x00/bcsr.h>
+#include <prom.h>
+
+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 || kstrtoul(memsize_str, 0, &memsize))
+ memsize = 64 << 20; /* all devboards have at least 64MB RAM */
+
+ add_memory_region(0, memsize, BOOT_MEM_RAM);
+}
+
+void prom_putchar(unsigned char c)
+{
+#ifdef CONFIG_MIPS_DB1300
+ alchemy_uart_putchar(AU1300_UART2_PHYS_ADDR, c);
+#else
+ alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
+#endif
+}
+
static struct platform_device db1x00_rtc_dev = {
.name = "rtc-au1xxx",
diff --git a/arch/mips/alchemy/devboards/prom.c b/arch/mips/alchemy/devboards/prom.c
deleted file mode 100644
index 93a22107cc4..00000000000
--- a/arch/mips/alchemy/devboards/prom.c
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Common code used by all Alchemy develboards.
- *
- * Extracted from files which had this to say:
- *
- * 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
- * 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 <asm/mach-au1x00/au1000.h>
-#include <prom.h>
-
-#if defined(CONFIG_MIPS_DB1000) || \
- defined(CONFIG_MIPS_PB1100) || \
- defined(CONFIG_MIPS_PB1500)
-#define ALCHEMY_BOARD_DEFAULT_MEMSIZE 0x04000000
-
-#else /* Au1550/Au1200-based develboards */
-#define ALCHEMY_BOARD_DEFAULT_MEMSIZE 0x08000000
-#endif
-
-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 || strict_strtoul(memsize_str, 0, &memsize))
- memsize = ALCHEMY_BOARD_DEFAULT_MEMSIZE;
-
- add_memory_region(0, memsize, BOOT_MEM_RAM);
-}
-
-void prom_putchar(unsigned char c)
-{
-#ifdef CONFIG_MIPS_DB1300
- alchemy_uart_putchar(AU1300_UART2_PHYS_ADDR, c);
-#else
- alchemy_uart_putchar(AU1000_UART0_PHYS_ADDR, c);
-#endif
-}
diff --git a/arch/mips/bcm63xx/Kconfig b/arch/mips/bcm63xx/Kconfig
index 6b1b9ad8d85..d03e8799d1c 100644
--- a/arch/mips/bcm63xx/Kconfig
+++ b/arch/mips/bcm63xx/Kconfig
@@ -1,6 +1,10 @@
menu "CPU support"
depends on BCM63XX
+config BCM63XX_CPU_6328
+ bool "support 6328 CPU"
+ select HW_HAS_PCI
+
config BCM63XX_CPU_6338
bool "support 6338 CPU"
select HW_HAS_PCI
diff --git a/arch/mips/bcm63xx/Makefile b/arch/mips/bcm63xx/Makefile
index 6dfdc69928a..833af72c852 100644
--- a/arch/mips/bcm63xx/Makefile
+++ b/arch/mips/bcm63xx/Makefile
@@ -1,5 +1,6 @@
obj-y += clk.o cpu.o cs.o gpio.o irq.o prom.o setup.o timer.o \
- dev-dsp.o dev-enet.o dev-pcmcia.o dev-uart.o dev-wdt.o
+ dev-dsp.o dev-enet.o dev-flash.o dev-pcmcia.o dev-rng.o \
+ dev-spi.o dev-uart.o dev-wdt.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-y += boards/
diff --git a/arch/mips/bcm63xx/boards/board_bcm963xx.c b/arch/mips/bcm63xx/boards/board_bcm963xx.c
index 2f1773f3fb7..feb05258a4d 100644
--- a/arch/mips/bcm63xx/boards/board_bcm963xx.c
+++ b/arch/mips/bcm63xx/boards/board_bcm963xx.c
@@ -11,9 +11,6 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/platform_device.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/physmap.h>
#include <linux/ssb/ssb.h>
#include <asm/addrspace.h>
#include <bcm63xx_board.h>
@@ -24,7 +21,9 @@
#include <bcm63xx_dev_pci.h>
#include <bcm63xx_dev_enet.h>
#include <bcm63xx_dev_dsp.h>
+#include <bcm63xx_dev_flash.h>
#include <bcm63xx_dev_pcmcia.h>
+#include <bcm63xx_dev_spi.h>
#include <board_bcm963xx.h>
#define PFX "board_bcm963xx: "
@@ -34,6 +33,48 @@ static unsigned int mac_addr_used;
static struct board_info board;
/*
+ * known 6328 boards
+ */
+#ifdef CONFIG_BCM63XX_CPU_6328
+static struct board_info __initdata board_96328avng = {
+ .name = "96328avng",
+ .expected_cpu_id = 0x6328,
+
+ .has_uart0 = 1,
+ .has_pci = 1,
+
+ .leds = {
+ {
+ .name = "96328avng::ppp-fail",
+ .gpio = 2,
+ .active_low = 1,
+ },
+ {
+ .name = "96328avng::power",
+ .gpio = 4,
+ .active_low = 1,
+ .default_trigger = "default-on",
+ },
+ {
+ .name = "96328avng::power-fail",
+ .gpio = 8,
+ .active_low = 1,
+ },
+ {
+ .name = "96328avng::wps",
+ .gpio = 9,
+ .active_low = 1,
+ },
+ {
+ .name = "96328avng::ppp",
+ .gpio = 11,
+ .active_low = 1,
+ },
+ },
+};
+#endif
+
+/*
* known 6338 boards
*/
#ifdef CONFIG_BCM63XX_CPU_6338
@@ -592,6 +633,9 @@ static struct board_info __initdata board_DWVS0 = {
* all boards
*/
static const struct board_info __initdata *bcm963xx_boards[] = {
+#ifdef CONFIG_BCM63XX_CPU_6328
+ &board_96328avng,
+#endif
#ifdef CONFIG_BCM63XX_CPU_6338
&board_96338gw,
&board_96338w,
@@ -709,9 +753,15 @@ void __init board_prom_init(void)
char cfe_version[32];
u32 val;
- /* read base address of boot chip select (0) */
- val = bcm_mpi_readl(MPI_CSBASE_REG(0));
- val &= MPI_CSBASE_BASE_MASK;
+ /* read base address of boot chip select (0)
+ * 6328 does not have MPI but boots from a fixed address
+ */
+ if (BCMCPU_IS_6328())
+ val = 0x18000000;
+ else {
+ val = bcm_mpi_readl(MPI_CSBASE_REG(0));
+ val &= MPI_CSBASE_BASE_MASK;
+ }
boot_addr = (u8 *)KSEG1ADDR(val);
/* dump cfe version */
@@ -808,40 +858,6 @@ void __init board_setup(void)
panic("unexpected CPU for bcm963xx board");
}
-static struct mtd_partition mtd_partitions[] = {
- {
- .name = "cfe",
- .offset = 0x0,
- .size = 0x40000,
- }
-};
-
-static const char *bcm63xx_part_types[] = { "bcm63xxpart", NULL };
-
-static struct physmap_flash_data flash_data = {
- .width = 2,
- .nr_parts = ARRAY_SIZE(mtd_partitions),
- .parts = mtd_partitions,
- .part_probe_types = bcm63xx_part_types,
-};
-
-static struct resource mtd_resources[] = {
- {
- .start = 0, /* filled at runtime */
- .end = 0, /* filled at runtime */
- .flags = IORESOURCE_MEM,
- }
-};
-
-static struct platform_device mtd_dev = {
- .name = "physmap-flash",
- .resource = mtd_resources,
- .num_resources = ARRAY_SIZE(mtd_resources),
- .dev = {
- .platform_data = &flash_data,
- },
-};
-
static struct gpio_led_platform_data bcm63xx_led_data;
static struct platform_device bcm63xx_gpio_leds = {
@@ -855,8 +871,6 @@ static struct platform_device bcm63xx_gpio_leds = {
*/
int __init board_register_devices(void)
{
- u32 val;
-
if (board.has_uart0)
bcm63xx_uart_register(0);
@@ -890,14 +904,9 @@ int __init board_register_devices(void)
}
#endif
- /* read base address of boot chip select (0) */
- val = bcm_mpi_readl(MPI_CSBASE_REG(0));
- val &= MPI_CSBASE_BASE_MASK;
-
- mtd_resources[0].start = val;
- mtd_resources[0].end = 0x1FFFFFFF;
+ bcm63xx_spi_register();
- platform_device_register(&mtd_dev);
+ bcm63xx_flash_register();
bcm63xx_led_data.num_leds = ARRAY_SIZE(board.leds);
bcm63xx_led_data.leds = board.leds;
diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c
index 9d57c71b7b5..1db48adb543 100644
--- a/arch/mips/bcm63xx/clk.c
+++ b/arch/mips/bcm63xx/clk.c
@@ -120,7 +120,7 @@ static void enetsw_set(struct clk *clk, int enable)
{
if (!BCMCPU_IS_6368())
return;
- bcm_hwclock_set(CKCTL_6368_ROBOSW_CLK_EN |
+ bcm_hwclock_set(CKCTL_6368_ROBOSW_EN |
CKCTL_6368_SWPKT_USB_EN |
CKCTL_6368_SWPKT_SAR_EN, enable);
if (enable) {
@@ -163,7 +163,7 @@ static void usbh_set(struct clk *clk, int enable)
if (BCMCPU_IS_6348())
bcm_hwclock_set(CKCTL_6348_USBH_EN, enable);
else if (BCMCPU_IS_6368())
- bcm_hwclock_set(CKCTL_6368_USBH_CLK_EN, enable);
+ bcm_hwclock_set(CKCTL_6368_USBH_EN, enable);
}
static struct clk clk_usbh = {
@@ -181,9 +181,11 @@ static void spi_set(struct clk *clk, int enable)
mask = CKCTL_6338_SPI_EN;
else if (BCMCPU_IS_6348())
mask = CKCTL_6348_SPI_EN;
- else
- /* BCMCPU_IS_6358 */
+ else if (BCMCPU_IS_6358())
mask = CKCTL_6358_SPI_EN;
+ else
+ /* BCMCPU_IS_6368 */
+ mask = CKCTL_6368_SPI_EN;
bcm_hwclock_set(mask, enable);
}
@@ -199,7 +201,7 @@ static void xtm_set(struct clk *clk, int enable)
if (!BCMCPU_IS_6368())
return;
- bcm_hwclock_set(CKCTL_6368_SAR_CLK_EN |
+ bcm_hwclock_set(CKCTL_6368_SAR_EN |
CKCTL_6368_SWPKT_SAR_EN, enable);
if (enable) {
@@ -222,6 +224,18 @@ static struct clk clk_xtm = {
};
/*
+ * IPsec clock
+ */
+static void ipsec_set(struct clk *clk, int enable)
+{
+ bcm_hwclock_set(CKCTL_6368_IPSEC_EN, enable);
+}
+
+static struct clk clk_ipsec = {
+ .set = ipsec_set,
+};
+
+/*
* Internal peripheral clock
*/
static struct clk clk_periph = {
@@ -278,6 +292,8 @@ struct clk *clk_get(struct device *dev, const char *id)
return &clk_periph;
if (BCMCPU_IS_6358() && !strcmp(id, "pcm"))
return &clk_pcm;
+ if (BCMCPU_IS_6368() && !strcmp(id, "ipsec"))
+ return &clk_ipsec;
return ERR_PTR(-ENOENT);
}
diff --git a/arch/mips/bcm63xx/cpu.c b/arch/mips/bcm63xx/cpu.c
index 8f0d6c7725e..a7afb289b15 100644
--- a/arch/mips/bcm63xx/cpu.c
+++ b/arch/mips/bcm63xx/cpu.c
@@ -29,6 +29,14 @@ static u16 bcm63xx_cpu_rev;
static unsigned int bcm63xx_cpu_freq;
static unsigned int bcm63xx_memory_size;
+static const unsigned long bcm6328_regs_base[] = {
+ __GEN_CPU_REGS_TABLE(6328)
+};
+
+static const int bcm6328_irqs[] = {
+ __GEN_CPU_IRQ_TABLE(6328)
+};
+
static const unsigned long bcm6338_regs_base[] = {
__GEN_CPU_REGS_TABLE(6338)
};
@@ -99,6 +107,33 @@ unsigned int bcm63xx_get_memory_size(void)
static unsigned int detect_cpu_clock(void)
{
switch (bcm63xx_get_cpu_id()) {
+ case BCM6328_CPU_ID:
+ {
+ unsigned int tmp, mips_pll_fcvo;
+
+ tmp = bcm_misc_readl(MISC_STRAPBUS_6328_REG);
+ mips_pll_fcvo = (tmp & STRAPBUS_6328_FCVO_MASK)
+ >> STRAPBUS_6328_FCVO_SHIFT;
+
+ switch (mips_pll_fcvo) {
+ case 0x12:
+ case 0x14:
+ case 0x19:
+ return 160000000;
+ case 0x1c:
+ return 192000000;
+ case 0x13:
+ case 0x15:
+ return 200000000;
+ case 0x1a:
+ return 384000000;
+ case 0x16:
+ return 400000000;
+ default:
+ return 320000000;
+ }
+
+ }
case BCM6338_CPU_ID:
/* BCM6338 has a fixed 240 Mhz frequency */
return 240000000;
@@ -170,6 +205,9 @@ static unsigned int detect_memory_size(void)
unsigned int cols = 0, rows = 0, is_32bits = 0, banks = 0;
u32 val;
+ if (BCMCPU_IS_6328())
+ return bcm_ddr_readl(DDR_CSEND_REG) << 24;
+
if (BCMCPU_IS_6345()) {
val = bcm_sdram_readl(SDRAM_MBASE_REG);
return (val * 8 * 1024 * 1024);
@@ -228,17 +266,26 @@ void __init bcm63xx_cpu_init(void)
bcm63xx_irqs = bcm6345_irqs;
break;
case CPU_BMIPS4350:
- switch (read_c0_prid() & 0xf0) {
- case 0x10:
+ if ((read_c0_prid() & 0xf0) == 0x10) {
expected_cpu_id = BCM6358_CPU_ID;
bcm63xx_regs_base = bcm6358_regs_base;
bcm63xx_irqs = bcm6358_irqs;
- break;
- case 0x30:
- expected_cpu_id = BCM6368_CPU_ID;
- bcm63xx_regs_base = bcm6368_regs_base;
- bcm63xx_irqs = bcm6368_irqs;
- break;
+ } else {
+ /* all newer chips have the same chip id location */
+ u16 chip_id = bcm_readw(BCM_6368_PERF_BASE);
+
+ switch (chip_id) {
+ case BCM6328_CPU_ID:
+ expected_cpu_id = BCM6328_CPU_ID;
+ bcm63xx_regs_base = bcm6328_regs_base;
+ bcm63xx_irqs = bcm6328_irqs;
+ break;
+ case BCM6368_CPU_ID:
+ expected_cpu_id = BCM6368_CPU_ID;
+ bcm63xx_regs_base = bcm6368_regs_base;
+ bcm63xx_irqs = bcm6368_irqs;
+ break;
+ }
}
break;
}
diff --git a/arch/mips/bcm63xx/dev-dsp.c b/arch/mips/bcm63xx/dev-dsp.c
index da46d1d3c77..5bb5b154c9b 100644
--- a/arch/mips/bcm63xx/dev-dsp.c
+++ b/arch/mips/bcm63xx/dev-dsp.c
@@ -31,7 +31,7 @@ static struct resource voip_dsp_resources[] = {
static struct platform_device bcm63xx_voip_dsp_device = {
.name = "bcm63xx-voip-dsp",
- .id = 0,
+ .id = -1,
.num_resources = ARRAY_SIZE(voip_dsp_resources),
.resource = voip_dsp_resources,
};
diff --git a/arch/mips/bcm63xx/dev-flash.c b/arch/mips/bcm63xx/dev-flash.c
new file mode 100644
index 00000000000..58371c7deac
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-flash.c
@@ -0,0 +1,123 @@
+/*
+ * Broadcom BCM63xx flash registration
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
+ * Copyright (C) 2008 Florian Fainelli <florian@openwrt.org>
+ * Copyright (C) 2012 Jonas Gorski <jonas.gorski@gmail.com>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/physmap.h>
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_flash.h>
+#include <bcm63xx_regs.h>
+#include <bcm63xx_io.h>
+
+static struct mtd_partition mtd_partitions[] = {
+ {
+ .name = "cfe",
+ .offset = 0x0,
+ .size = 0x40000,
+ }
+};
+
+static const char *bcm63xx_part_types[] = { "bcm63xxpart", NULL };
+
+static struct physmap_flash_data flash_data = {
+ .width = 2,
+ .parts = mtd_partitions,
+ .part_probe_types = bcm63xx_part_types,
+};
+
+static struct resource mtd_resources[] = {
+ {
+ .start = 0, /* filled at runtime */
+ .end = 0, /* filled at runtime */
+ .flags = IORESOURCE_MEM,
+ }
+};
+
+static struct platform_device mtd_dev = {
+ .name = "physmap-flash",
+ .resource = mtd_resources,
+ .num_resources = ARRAY_SIZE(mtd_resources),
+ .dev = {
+ .platform_data = &flash_data,
+ },
+};
+
+static int __init bcm63xx_detect_flash_type(void)
+{
+ u32 val;
+
+ switch (bcm63xx_get_cpu_id()) {
+ case BCM6328_CPU_ID:
+ val = bcm_misc_readl(MISC_STRAPBUS_6328_REG);
+ if (val & STRAPBUS_6328_BOOT_SEL_SERIAL)
+ return BCM63XX_FLASH_TYPE_SERIAL;
+ else
+ return BCM63XX_FLASH_TYPE_NAND;
+ case BCM6338_CPU_ID:
+ case BCM6345_CPU_ID:
+ case BCM6348_CPU_ID:
+ /* no way to auto detect so assume parallel */
+ return BCM63XX_FLASH_TYPE_PARALLEL;
+ case BCM6358_CPU_ID:
+ val = bcm_gpio_readl(GPIO_STRAPBUS_REG);
+ if (val & STRAPBUS_6358_BOOT_SEL_PARALLEL)
+ return BCM63XX_FLASH_TYPE_PARALLEL;
+ else
+ return BCM63XX_FLASH_TYPE_SERIAL;
+ case BCM6368_CPU_ID:
+ val = bcm_gpio_readl(GPIO_STRAPBUS_REG);
+ switch (val & STRAPBUS_6368_BOOT_SEL_MASK) {
+ case STRAPBUS_6368_BOOT_SEL_NAND:
+ return BCM63XX_FLASH_TYPE_NAND;
+ case STRAPBUS_6368_BOOT_SEL_SERIAL:
+ return BCM63XX_FLASH_TYPE_SERIAL;
+ case STRAPBUS_6368_BOOT_SEL_PARALLEL:
+ return BCM63XX_FLASH_TYPE_PARALLEL;
+ }
+ default:
+ return -EINVAL;
+ }
+}
+
+int __init bcm63xx_flash_register(void)
+{
+ int flash_type;
+ u32 val;
+
+ flash_type = bcm63xx_detect_flash_type();
+
+ switch (flash_type) {
+ case BCM63XX_FLASH_TYPE_PARALLEL:
+ /* read base address of boot chip select (0) */
+ val = bcm_mpi_readl(MPI_CSBASE_REG(0));
+ val &= MPI_CSBASE_BASE_MASK;
+
+ mtd_resources[0].start = val;
+ mtd_resources[0].end = 0x1FFFFFFF;
+
+ return platform_device_register(&mtd_dev);
+ case BCM63XX_FLASH_TYPE_SERIAL:
+ pr_warn("unsupported serial flash detected\n");
+ return -ENODEV;
+ case BCM63XX_FLASH_TYPE_NAND:
+ pr_warn("unsupported NAND flash detected\n");
+ return -ENODEV;
+ default:
+ pr_err("flash detection failed for BCM%x: %d\n",
+ bcm63xx_get_cpu_id(), flash_type);
+ return -ENODEV;
+ }
+}
diff --git a/arch/mips/bcm63xx/dev-rng.c b/arch/mips/bcm63xx/dev-rng.c
new file mode 100644
index 00000000000..d277b4dc6c6
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-rng.c
@@ -0,0 +1,40 @@
+/*
+ * 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) 2011 Florian Fainelli <florian@openwrt.org>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <bcm63xx_cpu.h>
+
+static struct resource rng_resources[] = {
+ {
+ .start = -1, /* filled at runtime */
+ .end = -1, /* filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device bcm63xx_rng_device = {
+ .name = "bcm63xx-rng",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(rng_resources),
+ .resource = rng_resources,
+};
+
+int __init bcm63xx_rng_register(void)
+{
+ if (!BCMCPU_IS_6368())
+ return -ENODEV;
+
+ rng_resources[0].start = bcm63xx_regset_address(RSET_RNG);
+ rng_resources[0].end = rng_resources[0].start;
+ rng_resources[0].end += RSET_RNG_SIZE - 1;
+
+ return platform_device_register(&bcm63xx_rng_device);
+}
+arch_initcall(bcm63xx_rng_register);
diff --git a/arch/mips/bcm63xx/dev-spi.c b/arch/mips/bcm63xx/dev-spi.c
new file mode 100644
index 00000000000..e39f73048d4
--- /dev/null
+++ b/arch/mips/bcm63xx/dev-spi.c
@@ -0,0 +1,119 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2009-2011 Florian Fainelli <florian@openwrt.org>
+ * Copyright (C) 2010 Tanguy Bouzeloc <tanguy.bouzeloc@efixo.com>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+
+#include <bcm63xx_cpu.h>
+#include <bcm63xx_dev_spi.h>
+#include <bcm63xx_regs.h>
+
+#ifdef BCMCPU_RUNTIME_DETECT
+/*
+ * register offsets
+ */
+static const unsigned long bcm6338_regs_spi[] = {
+ __GEN_SPI_REGS_TABLE(6338)
+};
+
+static const unsigned long bcm6348_regs_spi[] = {
+ __GEN_SPI_REGS_TABLE(6348)
+};
+
+static const unsigned long bcm6358_regs_spi[] = {
+ __GEN_SPI_REGS_TABLE(6358)
+};
+
+static const unsigned long bcm6368_regs_spi[] = {
+ __GEN_SPI_REGS_TABLE(6368)
+};
+
+const unsigned long *bcm63xx_regs_spi;
+EXPORT_SYMBOL(bcm63xx_regs_spi);
+
+static __init void bcm63xx_spi_regs_init(void)
+{
+ if (BCMCPU_IS_6338())
+ bcm63xx_regs_spi = bcm6338_regs_spi;
+ if (BCMCPU_IS_6348())
+ bcm63xx_regs_spi = bcm6348_regs_spi;
+ if (BCMCPU_IS_6358())
+ bcm63xx_regs_spi = bcm6358_regs_spi;
+ if (BCMCPU_IS_6368())
+ bcm63xx_regs_spi = bcm6368_regs_spi;
+}
+#else
+static __init void bcm63xx_spi_regs_init(void) { }
+#endif
+
+static struct resource spi_resources[] = {
+ {
+ .start = -1, /* filled at runtime */
+ .end = -1, /* filled at runtime */
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .start = -1, /* filled at runtime */
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct bcm63xx_spi_pdata spi_pdata = {
+ .bus_num = 0,
+ .num_chipselect = 8,
+};
+
+static struct platform_device bcm63xx_spi_device = {
+ .name = "bcm63xx-spi",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(spi_resources),
+ .resource = spi_resources,
+ .dev = {
+ .platform_data = &spi_pdata,
+ },
+};
+
+int __init bcm63xx_spi_register(void)
+{
+ struct clk *periph_clk;
+
+ if (BCMCPU_IS_6328() || BCMCPU_IS_6345())
+ return -ENODEV;
+
+ periph_clk = clk_get(NULL, "periph");
+ if (IS_ERR(periph_clk)) {
+ pr_err("unable to get periph clock\n");
+ return -ENODEV;
+ }
+
+ /* Set bus frequency */
+ spi_pdata.speed_hz = clk_get_rate(periph_clk);
+
+ spi_resources[0].start = bcm63xx_regset_address(RSET_SPI);
+ spi_resources[0].end = spi_resources[0].start;
+ spi_resources[1].start = bcm63xx_get_irq_number(IRQ_SPI);
+
+ if (BCMCPU_IS_6338() || BCMCPU_IS_6348()) {
+ spi_resources[0].end += BCM_6338_RSET_SPI_SIZE - 1;
+ spi_pdata.fifo_size = SPI_6338_MSG_DATA_SIZE;
+ }
+
+ if (BCMCPU_IS_6358() || BCMCPU_IS_6368()) {
+ spi_resources[0].end += BCM_6358_RSET_SPI_SIZE - 1;
+ spi_pdata.fifo_size = SPI_6358_MSG_DATA_SIZE;
+ }
+
+ bcm63xx_spi_regs_init();
+
+ return platform_device_register(&bcm63xx_spi_device);
+}
diff --git a/arch/mips/bcm63xx/dev-wdt.c b/arch/mips/bcm63xx/dev-wdt.c
index 3e6c716a4c1..2a2346a99bc 100644
--- a/arch/mips/bcm63xx/dev-wdt.c
+++ b/arch/mips/bcm63xx/dev-wdt.c
@@ -21,7 +21,7 @@ static struct resource wdt_resources[] = {
static struct platform_device bcm63xx_wdt_device = {
.name = "bcm63xx-wdt",
- .id = 0,
+ .id = -1,
.num_resources = ARRAY_SIZE(wdt_resources),
.resource = wdt_resources,
};
diff --git a/arch/mips/bcm63xx/irq.c b/arch/mips/bcm63xx/irq.c
index 9a216a451d9..18e051ad18a 100644
--- a/arch/mips/bcm63xx/irq.c
+++ b/arch/mips/bcm63xx/irq.c
@@ -27,6 +27,17 @@ static void __internal_irq_unmask_32(unsigned int irq) __maybe_unused;
static void __internal_irq_unmask_64(unsigned int irq) __maybe_unused;
#ifndef BCMCPU_RUNTIME_DETECT
+#ifdef CONFIG_BCM63XX_CPU_6328
+#define irq_stat_reg PERF_IRQSTAT_6328_REG
+#define irq_mask_reg PERF_IRQMASK_6328_REG
+#define irq_bits 64
+#define is_ext_irq_cascaded 1
+#define ext_irq_start (BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE)
+#define ext_irq_end (BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE)
+#define ext_irq_count 4
+#define ext_irq_cfg_reg1 PERF_EXTIRQ_CFG_REG_6328
+#define ext_irq_cfg_reg2 0
+#endif
#ifdef CONFIG_BCM63XX_CPU_6338
#define irq_stat_reg PERF_IRQSTAT_6338_REG
#define irq_mask_reg PERF_IRQMASK_6338_REG
@@ -118,6 +129,16 @@ static void bcm63xx_init_irq(void)
irq_mask_addr = bcm63xx_regset_address(RSET_PERF);
switch (bcm63xx_get_cpu_id()) {
+ case BCM6328_CPU_ID:
+ irq_stat_addr += PERF_IRQSTAT_6328_REG;
+ irq_mask_addr += PERF_IRQMASK_6328_REG;
+ irq_bits = 64;
+ ext_irq_count = 4;
+ is_ext_irq_cascaded = 1;
+ ext_irq_start = BCM_6328_EXT_IRQ0 - IRQ_INTERNAL_BASE;
+ ext_irq_end = BCM_6328_EXT_IRQ3 - IRQ_INTERNAL_BASE;
+ ext_irq_cfg_reg1 = PERF_EXTIRQ_CFG_REG_6328;
+ break;
case BCM6338_CPU_ID:
irq_stat_addr += PERF_IRQSTAT_6338_REG;
irq_mask_addr += PERF_IRQMASK_6338_REG;
diff --git a/arch/mips/bcm63xx/prom.c b/arch/mips/bcm63xx/prom.c
index 99d7f405cbe..10eaff45807 100644
--- a/arch/mips/bcm63xx/prom.c
+++ b/arch/mips/bcm63xx/prom.c
@@ -26,7 +26,9 @@ void __init prom_init(void)
bcm_wdt_writel(WDT_STOP_2, WDT_CTL_REG);
/* disable all hardware blocks clock for now */
- if (BCMCPU_IS_6338())
+ if (BCMCPU_IS_6328())
+ mask = CKCTL_6328_ALL_SAFE_EN;
+ else if (BCMCPU_IS_6338())
mask = CKCTL_6338_ALL_SAFE_EN;
else if (BCMCPU_IS_6345())
mask = CKCTL_6345_ALL_SAFE_EN;
diff --git a/arch/mips/bcm63xx/setup.c b/arch/mips/bcm63xx/setup.c
index 356b05583e1..0e74a13639c 100644
--- a/arch/mips/bcm63xx/setup.c
+++ b/arch/mips/bcm63xx/setup.c
@@ -68,6 +68,9 @@ void bcm63xx_machine_reboot(void)
/* mask and clear all external irq */
switch (bcm63xx_get_cpu_id()) {
+ case BCM6328_CPU_ID:
+ perf_regs[0] = PERF_EXTIRQ_CFG_REG_6328;
+ break;
case BCM6338_CPU_ID:
perf_regs[0] = PERF_EXTIRQ_CFG_REG_6338;
break;
@@ -95,9 +98,13 @@ void bcm63xx_machine_reboot(void)
bcm6348_a1_reboot();
printk(KERN_INFO "triggering watchdog soft-reset...\n");
- reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG);
- reg |= SYS_PLL_SOFT_RESET;
- bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG);
+ if (BCMCPU_IS_6328()) {
+ bcm_wdt_writel(1, WDT_SOFTRESET_REG);
+ } else {
+ reg = bcm_perf_readl(PERF_SYS_PLL_CTL_REG);
+ reg |= SYS_PLL_SOFT_RESET;
+ bcm_perf_writel(reg, PERF_SYS_PLL_CTL_REG);
+ }
while (1)
;
}
diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile
index 5042d51b051..c2a3fb0ffc8 100644
--- a/arch/mips/boot/compressed/Makefile
+++ b/arch/mips/boot/compressed/Makefile
@@ -58,8 +58,12 @@ $(obj)/piggy.o: $(obj)/dummy.o $(obj)/vmlinux.bin.z FORCE
# Calculate the load address of the compressed kernel image
hostprogs-y := calc_vmlinuz_load_addr
+ifeq ($(CONFIG_MACH_JZ4740),y)
+VMLINUZ_LOAD_ADDRESS := 0x80600000
+else
VMLINUZ_LOAD_ADDRESS = $(shell $(obj)/calc_vmlinuz_load_addr \
$(obj)/vmlinux.bin $(VMLINUX_LOAD_ADDRESS))
+endif
vmlinuzobjs-y += $(obj)/piggy.o
diff --git a/arch/mips/boot/compressed/uart-16550.c b/arch/mips/boot/compressed/uart-16550.c
index c9caaf4fbf6..1c7b739b6a1 100644
--- a/arch/mips/boot/compressed/uart-16550.c
+++ b/arch/mips/boot/compressed/uart-16550.c
@@ -18,6 +18,11 @@
#define PORT(offset) (CKSEG1ADDR(AR7_REGS_UART0) + (4 * offset))
#endif
+#ifdef CONFIG_MACH_JZ4740
+#define UART0_BASE 0xB0030000
+#define PORT(offset) (UART0_BASE + (4 * offset))
+#endif
+
#ifndef PORT
#error please define the serial port address for your own machine
#endif
diff --git a/arch/mips/cavium-octeon/.gitignore b/arch/mips/cavium-octeon/.gitignore
new file mode 100644
index 00000000000..39c968605ff
--- /dev/null
+++ b/arch/mips/cavium-octeon/.gitignore
@@ -0,0 +1,2 @@
+*.dtb.S
+*.dtb
diff --git a/arch/mips/cavium-octeon/Makefile b/arch/mips/cavium-octeon/Makefile
index 19eb0434269..bc96e2908f1 100644
--- a/arch/mips/cavium-octeon/Makefile
+++ b/arch/mips/cavium-octeon/Makefile
@@ -9,9 +9,25 @@
# Copyright (C) 2005-2009 Cavium Networks
#
+CFLAGS_octeon-platform.o = -I$(src)/../../../scripts/dtc/libfdt
+CFLAGS_setup.o = -I$(src)/../../../scripts/dtc/libfdt
+
obj-y := cpu.o setup.o serial.o octeon-platform.o octeon-irq.o csrc-octeon.o
obj-y += dma-octeon.o flash_setup.o
obj-y += octeon-memcpy.o
obj-y += executive/
obj-$(CONFIG_SMP) += smp.o
+
+DTS_FILES = octeon_3xxx.dts octeon_68xx.dts
+DTB_FILES = $(patsubst %.dts, %.dtb, $(DTS_FILES))
+
+obj-y += $(patsubst %.dts, %.dtb.o, $(DTS_FILES))
+
+$(obj)/%.dtb: $(src)/%.dts FORCE
+ $(call if_changed_dep,dtc)
+
+# Let's keep the .dtb files around in case we want to look at them.
+.SECONDARY: $(addprefix $(obj)/, $(DTB_FILES))
+
+clean-files += $(DTB_FILES) $(patsubst %.dtb, %.dtb.S, $(DTB_FILES))
diff --git a/arch/mips/cavium-octeon/executive/cvmx-fpa.c b/arch/mips/cavium-octeon/executive/cvmx-fpa.c
deleted file mode 100644
index ad44b8bd805..00000000000
--- a/arch/mips/cavium-octeon/executive/cvmx-fpa.c
+++ /dev/null
@@ -1,183 +0,0 @@
-/***********************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
- *
- * Support library for the hardware Free Pool Allocator.
- *
- *
- */
-
-#include "cvmx-config.h"
-#include "cvmx.h"
-#include "cvmx-fpa.h"
-#include "cvmx-ipd.h"
-
-/**
- * Current state of all the pools. Use access functions
- * instead of using it directly.
- */
-CVMX_SHARED cvmx_fpa_pool_info_t cvmx_fpa_pool_info[CVMX_FPA_NUM_POOLS];
-
-/**
- * Setup a FPA pool to control a new block of memory. The
- * buffer pointer must be a physical address.
- *
- * @pool: Pool to initialize
- * 0 <= pool < 8
- * @name: Constant character string to name this pool.
- * String is not copied.
- * @buffer: Pointer to the block of memory to use. This must be
- * accessible by all processors and external hardware.
- * @block_size: Size for each block controlled by the FPA
- * @num_blocks: Number of blocks
- *
- * Returns 0 on Success,
- * -1 on failure
- */
-int cvmx_fpa_setup_pool(uint64_t pool, const char *name, void *buffer,
- uint64_t block_size, uint64_t num_blocks)
-{
- char *ptr;
- if (!buffer) {
- cvmx_dprintf
- ("ERROR: cvmx_fpa_setup_pool: NULL buffer pointer!\n");
- return -1;
- }
- if (pool >= CVMX_FPA_NUM_POOLS) {
- cvmx_dprintf("ERROR: cvmx_fpa_setup_pool: Illegal pool!\n");
- return -1;
- }
-
- if (block_size < CVMX_FPA_MIN_BLOCK_SIZE) {
- cvmx_dprintf
- ("ERROR: cvmx_fpa_setup_pool: Block size too small.\n");
- return -1;
- }
-
- if (((unsigned long)buffer & (CVMX_FPA_ALIGNMENT - 1)) != 0) {
- cvmx_dprintf
- ("ERROR: cvmx_fpa_setup_pool: Buffer not aligned properly.\n");
- return -1;
- }
-
- cvmx_fpa_pool_info[pool].name = name;
- cvmx_fpa_pool_info[pool].size = block_size;
- cvmx_fpa_pool_info[pool].starting_element_count = num_blocks;
- cvmx_fpa_pool_info[pool].base = buffer;
-
- ptr = (char *)buffer;
- while (num_blocks--) {
- cvmx_fpa_free(ptr, pool, 0);
- ptr += block_size;
- }
- return 0;
-}
-
-/**
- * Shutdown a Memory pool and validate that it had all of
- * the buffers originally placed in it.
- *
- * @pool: Pool to shutdown
- * Returns Zero on success
- * - Positive is count of missing buffers
- * - Negative is too many buffers or corrupted pointers
- */
-uint64_t cvmx_fpa_shutdown_pool(uint64_t pool)
-{
- uint64_t errors = 0;
- uint64_t count = 0;
- uint64_t base = cvmx_ptr_to_phys(cvmx_fpa_pool_info[pool].base);
- uint64_t finish =
- base +
- cvmx_fpa_pool_info[pool].size *
- cvmx_fpa_pool_info[pool].starting_element_count;
- void *ptr;
- uint64_t address;
-
- count = 0;
- do {
- ptr = cvmx_fpa_alloc(pool);
- if (ptr)
- address = cvmx_ptr_to_phys(ptr);
- else
- address = 0;
- if (address) {
- if ((address >= base) && (address < finish) &&
- (((address -
- base) % cvmx_fpa_pool_info[pool].size) == 0)) {
- count++;
- } else {
- cvmx_dprintf
- ("ERROR: cvmx_fpa_shutdown_pool: Illegal address 0x%llx in pool %s(%d)\n",
- (unsigned long long)address,
- cvmx_fpa_pool_info[pool].name, (int)pool);
- errors++;
- }
- }
- } while (address);
-
-#ifdef CVMX_ENABLE_PKO_FUNCTIONS
- if (pool == 0)
- cvmx_ipd_free_ptr();
-#endif
-
- if (errors) {
- cvmx_dprintf
- ("ERROR: cvmx_fpa_shutdown_pool: Pool %s(%d) started at 0x%llx, ended at 0x%llx, with a step of 0x%llx\n",
- cvmx_fpa_pool_info[pool].name, (int)pool,
- (unsigned long long)base, (unsigned long long)finish,
- (unsigned long long)cvmx_fpa_pool_info[pool].size);
- return -errors;
- } else
- return 0;
-}
-
-uint64_t cvmx_fpa_get_block_size(uint64_t pool)
-{
- switch (pool) {
- case 0:
- return CVMX_FPA_POOL_0_SIZE;
- case 1:
- return CVMX_FPA_POOL_1_SIZE;
- case 2:
- return CVMX_FPA_POOL_2_SIZE;
- case 3:
- return CVMX_FPA_POOL_3_SIZE;
- case 4:
- return CVMX_FPA_POOL_4_SIZE;
- case 5:
- return CVMX_FPA_POOL_5_SIZE;
- case 6:
- return CVMX_FPA_POOL_6_SIZE;
- case 7:
- return CVMX_FPA_POOL_7_SIZE;
- default:
- return 0;
- }
-}
diff --git a/arch/mips/cavium-octeon/executive/cvmx-helper-fpa.c b/arch/mips/cavium-octeon/executive/cvmx-helper-fpa.c
deleted file mode 100644
index c239e5f4ab9..00000000000
--- a/arch/mips/cavium-octeon/executive/cvmx-helper-fpa.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/***********************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
- *
- * Helper functions for FPA setup.
- *
- */
-#include "executive-config.h"
-#include "cvmx-config.h"
-#include "cvmx.h"
-#include "cvmx-bootmem.h"
-#include "cvmx-fpa.h"
-#include "cvmx-helper-fpa.h"
-
-/**
- * Allocate memory for and initialize a single FPA pool.
- *
- * @pool: Pool to initialize
- * @buffer_size: Size of buffers to allocate in bytes
- * @buffers: Number of buffers to put in the pool. Zero is allowed
- * @name: String name of the pool for debugging purposes
- * Returns Zero on success, non-zero on failure
- */
-static int __cvmx_helper_initialize_fpa_pool(int pool, uint64_t buffer_size,
- uint64_t buffers, const char *name)
-{
- uint64_t current_num;
- void *memory;
- uint64_t align = CVMX_CACHE_LINE_SIZE;
-
- /*
- * Align the allocation so that power of 2 size buffers are
- * naturally aligned.
- */
- while (align < buffer_size)
- align = align << 1;
-
- if (buffers == 0)
- return 0;
-
- current_num = cvmx_read_csr(CVMX_FPA_QUEX_AVAILABLE(pool));
- if (current_num) {
- cvmx_dprintf("Fpa pool %d(%s) already has %llu buffers. "
- "Skipping setup.\n",
- pool, name, (unsigned long long)current_num);
- return 0;
- }
-
- memory = cvmx_bootmem_alloc(buffer_size * buffers, align);
- if (memory == NULL) {
- cvmx_dprintf("Out of memory initializing fpa pool %d(%s).\n",
- pool, name);
- return -1;
- }
- cvmx_fpa_setup_pool(pool, name, memory, buffer_size, buffers);
- return 0;
-}
-
-/**
- * Allocate memory and initialize the FPA pools using memory
- * from cvmx-bootmem. Specifying zero for the number of
- * buffers will cause that FPA pool to not be setup. This is
- * useful if you aren't using some of the hardware and want
- * to save memory. Use cvmx_helper_initialize_fpa instead of
- * this function directly.
- *
- * @pip_pool: Should always be CVMX_FPA_PACKET_POOL
- * @pip_size: Should always be CVMX_FPA_PACKET_POOL_SIZE
- * @pip_buffers:
- * Number of packet buffers.
- * @wqe_pool: Should always be CVMX_FPA_WQE_POOL
- * @wqe_size: Should always be CVMX_FPA_WQE_POOL_SIZE
- * @wqe_entries:
- * Number of work queue entries
- * @pko_pool: Should always be CVMX_FPA_OUTPUT_BUFFER_POOL
- * @pko_size: Should always be CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE
- * @pko_buffers:
- * PKO Command buffers. You should at minimum have two per
- * each PKO queue.
- * @tim_pool: Should always be CVMX_FPA_TIMER_POOL
- * @tim_size: Should always be CVMX_FPA_TIMER_POOL_SIZE
- * @tim_buffers:
- * TIM ring buffer command queues. At least two per timer bucket
- * is recommened.
- * @dfa_pool: Should always be CVMX_FPA_DFA_POOL
- * @dfa_size: Should always be CVMX_FPA_DFA_POOL_SIZE
- * @dfa_buffers:
- * DFA command buffer. A relatively small (32 for example)
- * number should work.
- * Returns Zero on success, non-zero if out of memory
- */
-static int __cvmx_helper_initialize_fpa(int pip_pool, int pip_size,
- int pip_buffers, int wqe_pool,
- int wqe_size, int wqe_entries,
- int pko_pool, int pko_size,
- int pko_buffers, int tim_pool,
- int tim_size, int tim_buffers,
- int dfa_pool, int dfa_size,
- int dfa_buffers)
-{
- int status;
-
- cvmx_fpa_enable();
-
- if ((pip_buffers > 0) && (pip_buffers <= 64))
- cvmx_dprintf
- ("Warning: %d packet buffers may not be enough for hardware"
- " prefetch. 65 or more is recommended.\n", pip_buffers);
-
- if (pip_pool >= 0) {
- status =
- __cvmx_helper_initialize_fpa_pool(pip_pool, pip_size,
- pip_buffers,
- "Packet Buffers");
- if (status)
- return status;
- }
-
- if (wqe_pool >= 0) {
- status =
- __cvmx_helper_initialize_fpa_pool(wqe_pool, wqe_size,
- wqe_entries,
- "Work Queue Entries");
- if (status)
- return status;
- }
-
- if (pko_pool >= 0) {
- status =
- __cvmx_helper_initialize_fpa_pool(pko_pool, pko_size,
- pko_buffers,
- "PKO Command Buffers");
- if (status)
- return status;
- }
-
- if (tim_pool >= 0) {
- status =
- __cvmx_helper_initialize_fpa_pool(tim_pool, tim_size,
- tim_buffers,
- "TIM Command Buffers");
- if (status)
- return status;
- }
-
- if (dfa_pool >= 0) {
- status =
- __cvmx_helper_initialize_fpa_pool(dfa_pool, dfa_size,
- dfa_buffers,
- "DFA Command Buffers");
- if (status)
- return status;
- }
-
- return 0;
-}
-
-/**
- * Allocate memory and initialize the FPA pools using memory
- * from cvmx-bootmem. Sizes of each element in the pools is
- * controlled by the cvmx-config.h header file. Specifying
- * zero for any parameter will cause that FPA pool to not be
- * setup. This is useful if you aren't using some of the
- * hardware and want to save memory.
- *
- * @packet_buffers:
- * Number of packet buffers to allocate
- * @work_queue_entries:
- * Number of work queue entries
- * @pko_buffers:
- * PKO Command buffers. You should at minimum have two per
- * each PKO queue.
- * @tim_buffers:
- * TIM ring buffer command queues. At least two per timer bucket
- * is recommened.
- * @dfa_buffers:
- * DFA command buffer. A relatively small (32 for example)
- * number should work.
- * Returns Zero on success, non-zero if out of memory
- */
-int cvmx_helper_initialize_fpa(int packet_buffers, int work_queue_entries,
- int pko_buffers, int tim_buffers,
- int dfa_buffers)
-{
-#ifndef CVMX_FPA_PACKET_POOL
-#define CVMX_FPA_PACKET_POOL -1
-#define CVMX_FPA_PACKET_POOL_SIZE 0
-#endif
-#ifndef CVMX_FPA_WQE_POOL
-#define CVMX_FPA_WQE_POOL -1
-#define CVMX_FPA_WQE_POOL_SIZE 0
-#endif
-#ifndef CVMX_FPA_OUTPUT_BUFFER_POOL
-#define CVMX_FPA_OUTPUT_BUFFER_POOL -1
-#define CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE 0
-#endif
-#ifndef CVMX_FPA_TIMER_POOL
-#define CVMX_FPA_TIMER_POOL -1
-#define CVMX_FPA_TIMER_POOL_SIZE 0
-#endif
-#ifndef CVMX_FPA_DFA_POOL
-#define CVMX_FPA_DFA_POOL -1
-#define CVMX_FPA_DFA_POOL_SIZE 0
-#endif
- return __cvmx_helper_initialize_fpa(CVMX_FPA_PACKET_POOL,
- CVMX_FPA_PACKET_POOL_SIZE,
- packet_buffers, CVMX_FPA_WQE_POOL,
- CVMX_FPA_WQE_POOL_SIZE,
- work_queue_entries,
- CVMX_FPA_OUTPUT_BUFFER_POOL,
- CVMX_FPA_OUTPUT_BUFFER_POOL_SIZE,
- pko_buffers, CVMX_FPA_TIMER_POOL,
- CVMX_FPA_TIMER_POOL_SIZE,
- tim_buffers, CVMX_FPA_DFA_POOL,
- CVMX_FPA_DFA_POOL_SIZE,
- dfa_buffers);
-}
diff --git a/arch/mips/cavium-octeon/octeon-irq.c b/arch/mips/cavium-octeon/octeon-irq.c
index ffd4ae660f7..7fb1f222b8a 100644
--- a/arch/mips/cavium-octeon/octeon-irq.c
+++ b/arch/mips/cavium-octeon/octeon-irq.c
@@ -3,14 +3,17 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2004-2008, 2009, 2010, 2011 Cavium Networks
+ * Copyright (C) 2004-2012 Cavium, Inc.
*/
#include <linux/interrupt.h>
+#include <linux/irqdomain.h>
#include <linux/bitops.h>
#include <linux/percpu.h>
+#include <linux/slab.h>
#include <linux/irq.h>
#include <linux/smp.h>
+#include <linux/of.h>
#include <asm/octeon/octeon.h>
@@ -42,9 +45,9 @@ struct octeon_core_chip_data {
static struct octeon_core_chip_data octeon_irq_core_chip_data[MIPS_CORE_IRQ_LINES];
-static void __init octeon_irq_set_ciu_mapping(int irq, int line, int bit,
- struct irq_chip *chip,
- irq_flow_handler_t handler)
+static void octeon_irq_set_ciu_mapping(int irq, int line, int bit,
+ struct irq_chip *chip,
+ irq_flow_handler_t handler)
{
union octeon_ciu_chip_data cd;
@@ -505,6 +508,85 @@ static void octeon_irq_ciu_enable_all_v2(struct irq_data *data)
}
}
+static void octeon_irq_gpio_setup(struct irq_data *data)
+{
+ union cvmx_gpio_bit_cfgx cfg;
+ union octeon_ciu_chip_data cd;
+ u32 t = irqd_get_trigger_type(data);
+
+ cd.p = irq_data_get_irq_chip_data(data);
+
+ cfg.u64 = 0;
+ cfg.s.int_en = 1;
+ cfg.s.int_type = (t & IRQ_TYPE_EDGE_BOTH) != 0;
+ cfg.s.rx_xor = (t & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) != 0;
+
+ /* 140 nS glitch filter*/
+ cfg.s.fil_cnt = 7;
+ cfg.s.fil_sel = 3;
+
+ cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.bit - 16), cfg.u64);
+}
+
+static void octeon_irq_ciu_enable_gpio_v2(struct irq_data *data)
+{
+ octeon_irq_gpio_setup(data);
+ octeon_irq_ciu_enable_v2(data);
+}
+
+static void octeon_irq_ciu_enable_gpio(struct irq_data *data)
+{
+ octeon_irq_gpio_setup(data);
+ octeon_irq_ciu_enable(data);
+}
+
+static int octeon_irq_ciu_gpio_set_type(struct irq_data *data, unsigned int t)
+{
+ irqd_set_trigger_type(data, t);
+ octeon_irq_gpio_setup(data);
+
+ return IRQ_SET_MASK_OK;
+}
+
+static void octeon_irq_ciu_disable_gpio_v2(struct irq_data *data)
+{
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+ cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.bit - 16), 0);
+
+ octeon_irq_ciu_disable_all_v2(data);
+}
+
+static void octeon_irq_ciu_disable_gpio(struct irq_data *data)
+{
+ union octeon_ciu_chip_data cd;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+ cvmx_write_csr(CVMX_GPIO_BIT_CFGX(cd.s.bit - 16), 0);
+
+ octeon_irq_ciu_disable_all(data);
+}
+
+static void octeon_irq_ciu_gpio_ack(struct irq_data *data)
+{
+ union octeon_ciu_chip_data cd;
+ u64 mask;
+
+ cd.p = irq_data_get_irq_chip_data(data);
+ mask = 1ull << (cd.s.bit - 16);
+
+ cvmx_write_csr(CVMX_GPIO_INT_CLR, mask);
+}
+
+static void octeon_irq_handle_gpio(unsigned int irq, struct irq_desc *desc)
+{
+ if (irqd_get_trigger_type(irq_desc_get_irq_data(desc)) & IRQ_TYPE_EDGE_BOTH)
+ handle_edge_irq(irq, desc);
+ else
+ handle_level_irq(irq, desc);
+}
+
#ifdef CONFIG_SMP
static void octeon_irq_cpu_offline_ciu(struct irq_data *data)
@@ -650,18 +732,6 @@ static struct irq_chip octeon_irq_chip_ciu_v2 = {
.name = "CIU",
.irq_enable = octeon_irq_ciu_enable_v2,
.irq_disable = octeon_irq_ciu_disable_all_v2,
- .irq_mask = octeon_irq_ciu_disable_local_v2,
- .irq_unmask = octeon_irq_ciu_enable_v2,
-#ifdef CONFIG_SMP
- .irq_set_affinity = octeon_irq_ciu_set_affinity_v2,
- .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
-#endif
-};
-
-static struct irq_chip octeon_irq_chip_ciu_edge_v2 = {
- .name = "CIU-E",
- .irq_enable = octeon_irq_ciu_enable_v2,
- .irq_disable = octeon_irq_ciu_disable_all_v2,
.irq_ack = octeon_irq_ciu_ack,
.irq_mask = octeon_irq_ciu_disable_local_v2,
.irq_unmask = octeon_irq_ciu_enable_v2,
@@ -675,19 +745,8 @@ static struct irq_chip octeon_irq_chip_ciu = {
.name = "CIU",
.irq_enable = octeon_irq_ciu_enable,
.irq_disable = octeon_irq_ciu_disable_all,
- .irq_mask = octeon_irq_dummy_mask,
-#ifdef CONFIG_SMP
- .irq_set_affinity = octeon_irq_ciu_set_affinity,
- .irq_cpu_offline = octeon_irq_cpu_offline_ciu,
-#endif
-};
-
-static struct irq_chip octeon_irq_chip_ciu_edge = {
- .name = "CIU-E",
- .irq_enable = octeon_irq_ciu_enable,
- .irq_disable = octeon_irq_ciu_disable_all,
- .irq_mask = octeon_irq_dummy_mask,
.irq_ack = octeon_irq_ciu_ack,
+ .irq_mask = octeon_irq_dummy_mask,
#ifdef CONFIG_SMP
.irq_set_affinity = octeon_irq_ciu_set_affinity,
.irq_cpu_offline = octeon_irq_cpu_offline_ciu,
@@ -717,6 +776,33 @@ static struct irq_chip octeon_irq_chip_ciu_mbox = {
.flags = IRQCHIP_ONOFFLINE_ENABLED,
};
+static struct irq_chip octeon_irq_chip_ciu_gpio_v2 = {
+ .name = "CIU-GPIO",
+ .irq_enable = octeon_irq_ciu_enable_gpio_v2,
+ .irq_disable = octeon_irq_ciu_disable_gpio_v2,
+ .irq_ack = octeon_irq_ciu_gpio_ack,
+ .irq_mask = octeon_irq_ciu_disable_local_v2,
+ .irq_unmask = octeon_irq_ciu_enable_v2,
+ .irq_set_type = octeon_irq_ciu_gpio_set_type,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = octeon_irq_ciu_set_affinity_v2,
+#endif
+ .flags = IRQCHIP_SET_TYPE_MASKED,
+};
+
+static struct irq_chip octeon_irq_chip_ciu_gpio = {
+ .name = "CIU-GPIO",
+ .irq_enable = octeon_irq_ciu_enable_gpio,
+ .irq_disable = octeon_irq_ciu_disable_gpio,
+ .irq_mask = octeon_irq_dummy_mask,
+ .irq_ack = octeon_irq_ciu_gpio_ack,
+ .irq_set_type = octeon_irq_ciu_gpio_set_type,
+#ifdef CONFIG_SMP
+ .irq_set_affinity = octeon_irq_ciu_set_affinity,
+#endif
+ .flags = IRQCHIP_SET_TYPE_MASKED,
+};
+
/*
* Watchdog interrupts are special. They are associated with a single
* core, so we hardwire the affinity to that core.
@@ -764,6 +850,178 @@ static struct irq_chip octeon_irq_chip_ciu_wd = {
.irq_mask = octeon_irq_dummy_mask,
};
+static bool octeon_irq_ciu_is_edge(unsigned int line, unsigned int bit)
+{
+ bool edge = false;
+
+ if (line == 0)
+ switch (bit) {
+ case 48 ... 49: /* GMX DRP */
+ case 50: /* IPD_DRP */
+ case 52 ... 55: /* Timers */
+ case 58: /* MPI */
+ edge = true;
+ break;
+ default:
+ break;
+ }
+ else /* line == 1 */
+ switch (bit) {
+ case 47: /* PTP */
+ edge = true;
+ break;
+ default:
+ break;
+ }
+ return edge;
+}
+
+struct octeon_irq_gpio_domain_data {
+ unsigned int base_hwirq;
+};
+
+static int octeon_irq_gpio_xlat(struct irq_domain *d,
+ struct device_node *node,
+ const u32 *intspec,
+ unsigned int intsize,
+ unsigned long *out_hwirq,
+ unsigned int *out_type)
+{
+ unsigned int type;
+ unsigned int pin;
+ unsigned int trigger;
+ struct octeon_irq_gpio_domain_data *gpiod;
+
+ if (d->of_node != node)
+ return -EINVAL;
+
+ if (intsize < 2)
+ return -EINVAL;
+
+ pin = intspec[0];
+ if (pin >= 16)
+ return -EINVAL;
+
+ trigger = intspec[1];
+
+ switch (trigger) {
+ case 1:
+ type = IRQ_TYPE_EDGE_RISING;
+ break;
+ case 2:
+ type = IRQ_TYPE_EDGE_FALLING;
+ break;
+ case 4:
+ type = IRQ_TYPE_LEVEL_HIGH;
+ break;
+ case 8:
+ type = IRQ_TYPE_LEVEL_LOW;
+ break;
+ default:
+ pr_err("Error: (%s) Invalid irq trigger specification: %x\n",
+ node->name,
+ trigger);
+ type = IRQ_TYPE_LEVEL_LOW;
+ break;
+ }
+ *out_type = type;
+ gpiod = d->host_data;
+ *out_hwirq = gpiod->base_hwirq + pin;
+
+ return 0;
+}
+
+static int octeon_irq_ciu_xlat(struct irq_domain *d,
+ struct device_node *node,
+ const u32 *intspec,
+ unsigned int intsize,
+ unsigned long *out_hwirq,
+ unsigned int *out_type)
+{
+ unsigned int ciu, bit;
+
+ ciu = intspec[0];
+ bit = intspec[1];
+
+ if (ciu > 1 || bit > 63)
+ return -EINVAL;
+
+ /* These are the GPIO lines */
+ if (ciu == 0 && bit >= 16 && bit < 32)
+ return -EINVAL;
+
+ *out_hwirq = (ciu << 6) | bit;
+ *out_type = 0;
+
+ return 0;
+}
+
+static struct irq_chip *octeon_irq_ciu_chip;
+static struct irq_chip *octeon_irq_gpio_chip;
+
+static bool octeon_irq_virq_in_range(unsigned int virq)
+{
+ /* We cannot let it overflow the mapping array. */
+ if (virq < (1ul << 8 * sizeof(octeon_irq_ciu_to_irq[0][0])))
+ return true;
+
+ WARN_ONCE(true, "virq out of range %u.\n", virq);
+ return false;
+}
+
+static int octeon_irq_ciu_map(struct irq_domain *d,
+ unsigned int virq, irq_hw_number_t hw)
+{
+ unsigned int line = hw >> 6;
+ unsigned int bit = hw & 63;
+
+ if (!octeon_irq_virq_in_range(virq))
+ return -EINVAL;
+
+ if (line > 1 || octeon_irq_ciu_to_irq[line][bit] != 0)
+ return -EINVAL;
+
+ if (octeon_irq_ciu_is_edge(line, bit))
+ octeon_irq_set_ciu_mapping(virq, line, bit,
+ octeon_irq_ciu_chip,
+ handle_edge_irq);
+ else
+ octeon_irq_set_ciu_mapping(virq, line, bit,
+ octeon_irq_ciu_chip,
+ handle_level_irq);
+
+ return 0;
+}
+
+static int octeon_irq_gpio_map(struct irq_domain *d,
+ unsigned int virq, irq_hw_number_t hw)
+{
+ unsigned int line = hw >> 6;
+ unsigned int bit = hw & 63;
+
+ if (!octeon_irq_virq_in_range(virq))
+ return -EINVAL;
+
+ if (line > 1 || octeon_irq_ciu_to_irq[line][bit] != 0)
+ return -EINVAL;
+
+ octeon_irq_set_ciu_mapping(virq, line, bit,
+ octeon_irq_gpio_chip,
+ octeon_irq_handle_gpio);
+
+ return 0;
+}
+
+static struct irq_domain_ops octeon_irq_domain_ciu_ops = {
+ .map = octeon_irq_ciu_map,
+ .xlate = octeon_irq_ciu_xlat,
+};
+
+static struct irq_domain_ops octeon_irq_domain_gpio_ops = {
+ .map = octeon_irq_gpio_map,
+ .xlate = octeon_irq_gpio_xlat,
+};
+
static void octeon_irq_ip2_v1(void)
{
const unsigned long core_id = cvmx_get_core_num();
@@ -887,9 +1145,10 @@ static void __init octeon_irq_init_ciu(void)
{
unsigned int i;
struct irq_chip *chip;
- struct irq_chip *chip_edge;
struct irq_chip *chip_mbox;
struct irq_chip *chip_wd;
+ struct device_node *gpio_node;
+ struct device_node *ciu_node;
octeon_irq_init_ciu_percpu();
octeon_irq_setup_secondary = octeon_irq_setup_secondary_ciu;
@@ -901,17 +1160,18 @@ static void __init octeon_irq_init_ciu(void)
octeon_irq_ip2 = octeon_irq_ip2_v2;
octeon_irq_ip3 = octeon_irq_ip3_v2;
chip = &octeon_irq_chip_ciu_v2;
- chip_edge = &octeon_irq_chip_ciu_edge_v2;
chip_mbox = &octeon_irq_chip_ciu_mbox_v2;
chip_wd = &octeon_irq_chip_ciu_wd_v2;
+ octeon_irq_gpio_chip = &octeon_irq_chip_ciu_gpio_v2;
} else {
octeon_irq_ip2 = octeon_irq_ip2_v1;
octeon_irq_ip3 = octeon_irq_ip3_v1;
chip = &octeon_irq_chip_ciu;
- chip_edge = &octeon_irq_chip_ciu_edge;
chip_mbox = &octeon_irq_chip_ciu_mbox;
chip_wd = &octeon_irq_chip_ciu_wd;
+ octeon_irq_gpio_chip = &octeon_irq_chip_ciu_gpio;
}
+ octeon_irq_ciu_chip = chip;
octeon_irq_ip4 = octeon_irq_ip4_mask;
/* Mips internal */
@@ -920,80 +1180,49 @@ static void __init octeon_irq_init_ciu(void)
/* CIU_0 */
for (i = 0; i < 16; i++)
octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WORKQ0, 0, i + 0, chip, handle_level_irq);
- for (i = 0; i < 16; i++)
- octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GPIO0, 0, i + 16, chip, handle_level_irq);
octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX0, 0, 32, chip_mbox, handle_percpu_irq);
octeon_irq_set_ciu_mapping(OCTEON_IRQ_MBOX1, 0, 33, chip_mbox, handle_percpu_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART0, 0, 34, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART1, 0, 35, chip, handle_level_irq);
-
for (i = 0; i < 4; i++)
octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_INT0, 0, i + 36, chip, handle_level_irq);
for (i = 0; i < 4; i++)
octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_PCI_MSI0, 0, i + 40, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI, 0, 45, chip, handle_level_irq);
octeon_irq_set_ciu_mapping(OCTEON_IRQ_RML, 0, 46, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_TRACE0, 0, 47, chip, handle_level_irq);
-
- for (i = 0; i < 2; i++)
- octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_GMX_DRP0, 0, i + 48, chip_edge, handle_edge_irq);
-
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD_DRP, 0, 50, chip_edge, handle_edge_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY_ZERO, 0, 51, chip_edge, handle_edge_irq);
-
for (i = 0; i < 4; i++)
- octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip_edge, handle_edge_irq);
+ octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_TIMER0, 0, i + 52, chip, handle_edge_irq);
octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB0, 0, 56, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_PCM, 0, 57, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_MPI, 0, 58, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_TWSI2, 0, 59, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_POWIQ, 0, 60, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPDPPTHR, 0, 61, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII0, 0, 62, chip, handle_level_irq);
octeon_irq_set_ciu_mapping(OCTEON_IRQ_BOOTDMA, 0, 63, chip, handle_level_irq);
/* CIU_1 */
for (i = 0; i < 16; i++)
octeon_irq_set_ciu_mapping(i + OCTEON_IRQ_WDOG0, 1, i + 0, chip_wd, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_UART2, 1, 16, chip, handle_level_irq);
octeon_irq_set_ciu_mapping(OCTEON_IRQ_USB1, 1, 17, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_MII1, 1, 18, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_NAND, 1, 19, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_MIO, 1, 20, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_IOB, 1, 21, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_FPA, 1, 22, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_POW, 1, 23, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_L2C, 1, 24, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_IPD, 1, 25, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_PIP, 1, 26, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_PKO, 1, 27, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_ZIP, 1, 28, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_TIM, 1, 29, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_RAD, 1, 30, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_KEY, 1, 31, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFA, 1, 32, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_USBCTL, 1, 33, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_SLI, 1, 34, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_DPI, 1, 35, chip, handle_level_irq);
-
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGX0, 1, 36, chip, handle_level_irq);
-
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_AGL, 1, 46, chip, handle_level_irq);
-
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_PTP, 1, 47, chip_edge, handle_edge_irq);
-
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM0, 1, 48, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_PEM1, 1, 49, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO0, 1, 50, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_SRIO1, 1, 51, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_LMC0, 1, 52, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_DFM, 1, 56, chip, handle_level_irq);
- octeon_irq_set_ciu_mapping(OCTEON_IRQ_RST, 1, 63, chip, handle_level_irq);
+
+ gpio_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-gpio");
+ if (gpio_node) {
+ struct octeon_irq_gpio_domain_data *gpiod;
+
+ gpiod = kzalloc(sizeof(*gpiod), GFP_KERNEL);
+ if (gpiod) {
+ /* gpio domain host_data is the base hwirq number. */
+ gpiod->base_hwirq = 16;
+ irq_domain_add_linear(gpio_node, 16, &octeon_irq_domain_gpio_ops, gpiod);
+ of_node_put(gpio_node);
+ } else
+ pr_warn("Cannot allocate memory for GPIO irq_domain.\n");
+ } else
+ pr_warn("Cannot find device node for cavium,octeon-3860-gpio.\n");
+
+ ciu_node = of_find_compatible_node(NULL, NULL, "cavium,octeon-3860-ciu");
+ if (ciu_node) {
+ irq_domain_add_tree(ciu_node, &octeon_irq_domain_ciu_ops, NULL);
+ of_node_put(ciu_node);
+ } else
+ pr_warn("Cannot find device node for cavium,octeon-3860-ciu.\n");
/* Enable the CIU lines */
set_c0_status(STATUSF_IP3 | STATUSF_IP2);
diff --git a/arch/mips/cavium-octeon/octeon-memcpy.S b/arch/mips/cavium-octeon/octeon-memcpy.S
index 88e0cddca20..db478dbb9c7 100644
--- a/arch/mips/cavium-octeon/octeon-memcpy.S
+++ b/arch/mips/cavium-octeon/octeon-memcpy.S
@@ -164,6 +164,14 @@
.set noat
/*
+ * t7 is used as a flag to note inatomic mode.
+ */
+LEAF(__copy_user_inatomic)
+ b __copy_user_common
+ li t7, 1
+ END(__copy_user_inatomic)
+
+/*
* A combined memcpy/__copy_user
* __copy_user sets len to 0 for success; else to an upper bound of
* the number of uncopied bytes.
@@ -174,6 +182,8 @@ LEAF(memcpy) /* a0=dst a1=src a2=len */
move v0, dst /* return value */
__memcpy:
FEXPORT(__copy_user)
+ li t7, 0 /* not inatomic */
+__copy_user_common:
/*
* Note: dst & src may be unaligned, len may be 0
* Temps
@@ -412,7 +422,6 @@ l_exc_copy:
* Assumes src < THREAD_BUADDR($28)
*/
LOAD t0, TI_TASK($28)
- nop
LOAD t0, THREAD_BUADDR(t0)
1:
EXC( lb t1, 0(src), l_exc)
@@ -422,10 +431,9 @@ EXC( lb t1, 0(src), l_exc)
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
+ bnez t7, 2f /* Skip the zeroing out part if inatomic */
/*
* Here's where we rely on src and dst being incremented in tandem,
* See (3) above.
@@ -443,7 +451,7 @@ l_exc:
ADD dst, dst, 1
bnez src, 1b
SUB src, src, 1
- jr ra
+2: jr ra
nop
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c
index cd61d7281d9..0938df10a71 100644
--- a/arch/mips/cavium-octeon/octeon-platform.c
+++ b/arch/mips/cavium-octeon/octeon-platform.c
@@ -3,7 +3,7 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*
- * Copyright (C) 2004-2010 Cavium Networks
+ * Copyright (C) 2004-2011 Cavium Networks
* Copyright (C) 2008 Wind River Systems
*/
@@ -13,10 +13,16 @@
#include <linux/usb.h>
#include <linux/dma-mapping.h>
#include <linux/module.h>
+#include <linux/slab.h>
#include <linux/platform_device.h>
+#include <linux/of_platform.h>
+#include <linux/of_fdt.h>
+#include <linux/libfdt.h>
#include <asm/octeon/octeon.h>
#include <asm/octeon/cvmx-rnm-defs.h>
+#include <asm/octeon/cvmx-helper.h>
+#include <asm/octeon/cvmx-helper-board.h>
static struct octeon_cf_data octeon_cf_data;
@@ -162,182 +168,6 @@ out:
}
device_initcall(octeon_rng_device_init);
-static struct i2c_board_info __initdata octeon_i2c_devices[] = {
- {
- I2C_BOARD_INFO("ds1337", 0x68),
- },
-};
-
-static int __init octeon_i2c_devices_init(void)
-{
- return i2c_register_board_info(0, octeon_i2c_devices,
- ARRAY_SIZE(octeon_i2c_devices));
-}
-arch_initcall(octeon_i2c_devices_init);
-
-#define OCTEON_I2C_IO_BASE 0x1180000001000ull
-#define OCTEON_I2C_IO_UNIT_OFFSET 0x200
-
-static struct octeon_i2c_data octeon_i2c_data[2];
-
-static int __init octeon_i2c_device_init(void)
-{
- struct platform_device *pd;
- int ret = 0;
- int port, num_ports;
-
- struct resource i2c_resources[] = {
- {
- .flags = IORESOURCE_MEM,
- }, {
- .flags = IORESOURCE_IRQ,
- }
- };
-
- if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX))
- num_ports = 2;
- else
- num_ports = 1;
-
- for (port = 0; port < num_ports; port++) {
- octeon_i2c_data[port].sys_freq = octeon_get_io_clock_rate();
- /*FIXME: should be examined. At the moment is set for 100Khz */
- octeon_i2c_data[port].i2c_freq = 100000;
-
- pd = platform_device_alloc("i2c-octeon", port);
- if (!pd) {
- ret = -ENOMEM;
- goto out;
- }
-
- pd->dev.platform_data = octeon_i2c_data + port;
-
- i2c_resources[0].start =
- OCTEON_I2C_IO_BASE + (port * OCTEON_I2C_IO_UNIT_OFFSET);
- i2c_resources[0].end = i2c_resources[0].start + 0x1f;
- switch (port) {
- case 0:
- i2c_resources[1].start = OCTEON_IRQ_TWSI;
- i2c_resources[1].end = OCTEON_IRQ_TWSI;
- break;
- case 1:
- i2c_resources[1].start = OCTEON_IRQ_TWSI2;
- i2c_resources[1].end = OCTEON_IRQ_TWSI2;
- break;
- default:
- BUG();
- }
-
- ret = platform_device_add_resources(pd,
- i2c_resources,
- ARRAY_SIZE(i2c_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_i2c_device_init);
-
-/* Octeon SMI/MDIO interface. */
-static int __init octeon_mdiobus_device_init(void)
-{
- struct platform_device *pd;
- int ret = 0;
-
- if (octeon_is_simulation())
- return 0; /* No mdio in the simulator. */
-
- /* The bus number is the platform_device id. */
- pd = platform_device_alloc("mdio-octeon", 0);
- if (!pd) {
- ret = -ENOMEM;
- goto out;
- }
-
- ret = platform_device_add(pd);
- if (ret)
- goto fail;
-
- return ret;
-fail:
- platform_device_put(pd);
-
-out:
- return ret;
-
-}
-device_initcall(octeon_mdiobus_device_init);
-
-/* Octeon mgmt port Ethernet interface. */
-static int __init octeon_mgmt_device_init(void)
-{
- struct platform_device *pd;
- int ret = 0;
- int port, num_ports;
-
- struct resource mgmt_port_resource = {
- .flags = IORESOURCE_IRQ,
- .start = -1,
- .end = -1
- };
-
- if (!OCTEON_IS_MODEL(OCTEON_CN56XX) && !OCTEON_IS_MODEL(OCTEON_CN52XX))
- return 0;
-
- if (OCTEON_IS_MODEL(OCTEON_CN56XX))
- num_ports = 1;
- else
- num_ports = 2;
-
- for (port = 0; port < num_ports; port++) {
- pd = platform_device_alloc("octeon_mgmt", port);
- if (!pd) {
- ret = -ENOMEM;
- goto out;
- }
- /* No DMA restrictions */
- pd->dev.coherent_dma_mask = DMA_BIT_MASK(64);
- pd->dev.dma_mask = &pd->dev.coherent_dma_mask;
-
- switch (port) {
- case 0:
- mgmt_port_resource.start = OCTEON_IRQ_MII0;
- break;
- case 1:
- mgmt_port_resource.start = OCTEON_IRQ_MII1;
- break;
- default:
- BUG();
- }
- mgmt_port_resource.end = mgmt_port_resource.start;
-
- ret = platform_device_add_resources(pd, &mgmt_port_resource, 1);
-
- 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_mgmt_device_init);
-
#ifdef CONFIG_USB
static int __init octeon_ehci_device_init(void)
@@ -440,6 +270,521 @@ device_initcall(octeon_ohci_device_init);
#endif /* CONFIG_USB */
+static struct of_device_id __initdata octeon_ids[] = {
+ { .compatible = "simple-bus", },
+ { .compatible = "cavium,octeon-6335-uctl", },
+ { .compatible = "cavium,octeon-3860-bootbus", },
+ { .compatible = "cavium,mdio-mux", },
+ { .compatible = "gpio-leds", },
+ {},
+};
+
+static bool __init octeon_has_88e1145(void)
+{
+ return !OCTEON_IS_MODEL(OCTEON_CN52XX) &&
+ !OCTEON_IS_MODEL(OCTEON_CN6XXX) &&
+ !OCTEON_IS_MODEL(OCTEON_CN56XX);
+}
+
+static void __init octeon_fdt_set_phy(int eth, int phy_addr)
+{
+ const __be32 *phy_handle;
+ const __be32 *alt_phy_handle;
+ const __be32 *reg;
+ u32 phandle;
+ int phy;
+ int alt_phy;
+ const char *p;
+ int current_len;
+ char new_name[20];
+
+ phy_handle = fdt_getprop(initial_boot_params, eth, "phy-handle", NULL);
+ if (!phy_handle)
+ return;
+
+ phandle = be32_to_cpup(phy_handle);
+ phy = fdt_node_offset_by_phandle(initial_boot_params, phandle);
+
+ alt_phy_handle = fdt_getprop(initial_boot_params, eth, "cavium,alt-phy-handle", NULL);
+ if (alt_phy_handle) {
+ u32 alt_phandle = be32_to_cpup(alt_phy_handle);
+ alt_phy = fdt_node_offset_by_phandle(initial_boot_params, alt_phandle);
+ } else {
+ alt_phy = -1;
+ }
+
+ if (phy_addr < 0 || phy < 0) {
+ /* Delete the PHY things */
+ fdt_nop_property(initial_boot_params, eth, "phy-handle");
+ /* This one may fail */
+ fdt_nop_property(initial_boot_params, eth, "cavium,alt-phy-handle");
+ if (phy >= 0)
+ fdt_nop_node(initial_boot_params, phy);
+ if (alt_phy >= 0)
+ fdt_nop_node(initial_boot_params, alt_phy);
+ return;
+ }
+
+ if (phy_addr >= 256 && alt_phy > 0) {
+ const struct fdt_property *phy_prop;
+ struct fdt_property *alt_prop;
+ u32 phy_handle_name;
+
+ /* Use the alt phy node instead.*/
+ phy_prop = fdt_get_property(initial_boot_params, eth, "phy-handle", NULL);
+ phy_handle_name = phy_prop->nameoff;
+ fdt_nop_node(initial_boot_params, phy);
+ fdt_nop_property(initial_boot_params, eth, "phy-handle");
+ alt_prop = fdt_get_property_w(initial_boot_params, eth, "cavium,alt-phy-handle", NULL);
+ alt_prop->nameoff = phy_handle_name;
+ phy = alt_phy;
+ }
+
+ phy_addr &= 0xff;
+
+ if (octeon_has_88e1145()) {
+ fdt_nop_property(initial_boot_params, phy, "marvell,reg-init");
+ memset(new_name, 0, sizeof(new_name));
+ strcpy(new_name, "marvell,88e1145");
+ p = fdt_getprop(initial_boot_params, phy, "compatible",
+ &current_len);
+ if (p && current_len >= strlen(new_name))
+ fdt_setprop_inplace(initial_boot_params, phy,
+ "compatible", new_name, current_len);
+ }
+
+ reg = fdt_getprop(initial_boot_params, phy, "reg", NULL);
+ if (phy_addr == be32_to_cpup(reg))
+ return;
+
+ fdt_setprop_inplace_cell(initial_boot_params, phy, "reg", phy_addr);
+
+ snprintf(new_name, sizeof(new_name), "ethernet-phy@%x", phy_addr);
+
+ p = fdt_get_name(initial_boot_params, phy, &current_len);
+ if (p && current_len == strlen(new_name))
+ fdt_set_name(initial_boot_params, phy, new_name);
+ else
+ pr_err("Error: could not rename ethernet phy: <%s>", p);
+}
+
+static void __init octeon_fdt_set_mac_addr(int n, u64 *pmac)
+{
+ u8 new_mac[6];
+ u64 mac = *pmac;
+ int r;
+
+ new_mac[0] = (mac >> 40) & 0xff;
+ new_mac[1] = (mac >> 32) & 0xff;
+ new_mac[2] = (mac >> 24) & 0xff;
+ new_mac[3] = (mac >> 16) & 0xff;
+ new_mac[4] = (mac >> 8) & 0xff;
+ new_mac[5] = mac & 0xff;
+
+ r = fdt_setprop_inplace(initial_boot_params, n, "local-mac-address",
+ new_mac, sizeof(new_mac));
+
+ if (r) {
+ pr_err("Setting \"local-mac-address\" failed %d", r);
+ return;
+ }
+ *pmac = mac + 1;
+}
+
+static void __init octeon_fdt_rm_ethernet(int node)
+{
+ const __be32 *phy_handle;
+
+ phy_handle = fdt_getprop(initial_boot_params, node, "phy-handle", NULL);
+ if (phy_handle) {
+ u32 ph = be32_to_cpup(phy_handle);
+ int p = fdt_node_offset_by_phandle(initial_boot_params, ph);
+ if (p >= 0)
+ fdt_nop_node(initial_boot_params, p);
+ }
+ fdt_nop_node(initial_boot_params, node);
+}
+
+static void __init octeon_fdt_pip_port(int iface, int i, int p, int max, u64 *pmac)
+{
+ char name_buffer[20];
+ int eth;
+ int phy_addr;
+ int ipd_port;
+
+ snprintf(name_buffer, sizeof(name_buffer), "ethernet@%x", p);
+ eth = fdt_subnode_offset(initial_boot_params, iface, name_buffer);
+ if (eth < 0)
+ return;
+ if (p > max) {
+ pr_debug("Deleting port %x:%x\n", i, p);
+ octeon_fdt_rm_ethernet(eth);
+ return;
+ }
+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
+ ipd_port = (0x100 * i) + (0x10 * p) + 0x800;
+ else
+ ipd_port = 16 * i + p;
+
+ phy_addr = cvmx_helper_board_get_mii_address(ipd_port);
+ octeon_fdt_set_phy(eth, phy_addr);
+ octeon_fdt_set_mac_addr(eth, pmac);
+}
+
+static void __init octeon_fdt_pip_iface(int pip, int idx, u64 *pmac)
+{
+ char name_buffer[20];
+ int iface;
+ int p;
+ int count;
+
+ count = cvmx_helper_interface_enumerate(idx);
+
+ snprintf(name_buffer, sizeof(name_buffer), "interface@%d", idx);
+ iface = fdt_subnode_offset(initial_boot_params, pip, name_buffer);
+ if (iface < 0)
+ return;
+
+ for (p = 0; p < 16; p++)
+ octeon_fdt_pip_port(iface, idx, p, count - 1, pmac);
+}
+
+int __init octeon_prune_device_tree(void)
+{
+ int i, max_port, uart_mask;
+ const char *pip_path;
+ const char *alias_prop;
+ char name_buffer[20];
+ int aliases;
+ u64 mac_addr_base;
+
+ if (fdt_check_header(initial_boot_params))
+ panic("Corrupt Device Tree.");
+
+ aliases = fdt_path_offset(initial_boot_params, "/aliases");
+ if (aliases < 0) {
+ pr_err("Error: No /aliases node in device tree.");
+ return -EINVAL;
+ }
+
+
+ mac_addr_base =
+ ((octeon_bootinfo->mac_addr_base[0] & 0xffull)) << 40 |
+ ((octeon_bootinfo->mac_addr_base[1] & 0xffull)) << 32 |
+ ((octeon_bootinfo->mac_addr_base[2] & 0xffull)) << 24 |
+ ((octeon_bootinfo->mac_addr_base[3] & 0xffull)) << 16 |
+ ((octeon_bootinfo->mac_addr_base[4] & 0xffull)) << 8 |
+ (octeon_bootinfo->mac_addr_base[5] & 0xffull);
+
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX) || OCTEON_IS_MODEL(OCTEON_CN63XX))
+ max_port = 2;
+ else if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN68XX))
+ max_port = 1;
+ else
+ max_port = 0;
+
+ if (octeon_bootinfo->board_type == CVMX_BOARD_TYPE_NIC10E)
+ max_port = 0;
+
+ for (i = 0; i < 2; i++) {
+ int mgmt;
+ snprintf(name_buffer, sizeof(name_buffer),
+ "mix%d", i);
+ alias_prop = fdt_getprop(initial_boot_params, aliases,
+ name_buffer, NULL);
+ if (alias_prop) {
+ mgmt = fdt_path_offset(initial_boot_params, alias_prop);
+ if (mgmt < 0)
+ continue;
+ if (i >= max_port) {
+ pr_debug("Deleting mix%d\n", i);
+ octeon_fdt_rm_ethernet(mgmt);
+ fdt_nop_property(initial_boot_params, aliases,
+ name_buffer);
+ } else {
+ int phy_addr = cvmx_helper_board_get_mii_address(CVMX_HELPER_BOARD_MGMT_IPD_PORT + i);
+ octeon_fdt_set_phy(mgmt, phy_addr);
+ octeon_fdt_set_mac_addr(mgmt, &mac_addr_base);
+ }
+ }
+ }
+
+ pip_path = fdt_getprop(initial_boot_params, aliases, "pip", NULL);
+ if (pip_path) {
+ int pip = fdt_path_offset(initial_boot_params, pip_path);
+ if (pip >= 0)
+ for (i = 0; i <= 4; i++)
+ octeon_fdt_pip_iface(pip, i, &mac_addr_base);
+ }
+
+ /* I2C */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN63XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN68XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN56XX))
+ max_port = 2;
+ else
+ max_port = 1;
+
+ for (i = 0; i < 2; i++) {
+ int i2c;
+ snprintf(name_buffer, sizeof(name_buffer),
+ "twsi%d", i);
+ alias_prop = fdt_getprop(initial_boot_params, aliases,
+ name_buffer, NULL);
+
+ if (alias_prop) {
+ i2c = fdt_path_offset(initial_boot_params, alias_prop);
+ if (i2c < 0)
+ continue;
+ if (i >= max_port) {
+ pr_debug("Deleting twsi%d\n", i);
+ fdt_nop_node(initial_boot_params, i2c);
+ fdt_nop_property(initial_boot_params, aliases,
+ name_buffer);
+ }
+ }
+ }
+
+ /* SMI/MDIO */
+ if (OCTEON_IS_MODEL(OCTEON_CN68XX))
+ max_port = 4;
+ else if (OCTEON_IS_MODEL(OCTEON_CN52XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN63XX) ||
+ OCTEON_IS_MODEL(OCTEON_CN56XX))
+ max_port = 2;
+ else
+ max_port = 1;
+
+ for (i = 0; i < 2; i++) {
+ int i2c;
+ snprintf(name_buffer, sizeof(name_buffer),
+ "smi%d", i);
+ alias_prop = fdt_getprop(initial_boot_params, aliases,
+ name_buffer, NULL);
+
+ if (alias_prop) {
+ i2c = fdt_path_offset(initial_boot_params, alias_prop);
+ if (i2c < 0)
+ continue;
+ if (i >= max_port) {
+ pr_debug("Deleting smi%d\n", i);
+ fdt_nop_node(initial_boot_params, i2c);
+ fdt_nop_property(initial_boot_params, aliases,
+ name_buffer);
+ }
+ }
+ }
+
+ /* Serial */
+ uart_mask = 3;
+
+ /* Right now CN52XX is the only chip with a third uart */
+ if (OCTEON_IS_MODEL(OCTEON_CN52XX))
+ uart_mask |= 4; /* uart2 */
+
+ for (i = 0; i < 3; i++) {
+ int uart;
+ snprintf(name_buffer, sizeof(name_buffer),
+ "uart%d", i);
+ alias_prop = fdt_getprop(initial_boot_params, aliases,
+ name_buffer, NULL);
+
+ if (alias_prop) {
+ uart = fdt_path_offset(initial_boot_params, alias_prop);
+ if (uart_mask & (1 << i))
+ continue;
+ pr_debug("Deleting uart%d\n", i);
+ fdt_nop_node(initial_boot_params, uart);
+ fdt_nop_property(initial_boot_params, aliases,
+ name_buffer);
+ }
+ }
+
+ /* Compact Flash */
+ alias_prop = fdt_getprop(initial_boot_params, aliases,
+ "cf0", NULL);
+ if (alias_prop) {
+ union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg;
+ unsigned long base_ptr, region_base, region_size;
+ unsigned long region1_base = 0;
+ unsigned long region1_size = 0;
+ int cs, bootbus;
+ bool is_16bit = false;
+ bool is_true_ide = false;
+ __be32 new_reg[6];
+ __be32 *ranges;
+ int len;
+
+ int cf = fdt_path_offset(initial_boot_params, alias_prop);
+ 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)
+ goto no_cf;
+
+ /* Find CS0 region. */
+ for (cs = 0; cs < 8; cs++) {
+ mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs));
+ 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) {
+ is_16bit = mio_boot_reg_cfg.s.width;
+ break;
+ }
+ }
+ if (cs >= 7) {
+ /* cs and cs + 1 are CS0 and CS1, both must be less than 8. */
+ goto no_cf;
+ }
+
+ 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(cs + 1));
+ region1_base = mio_boot_reg_cfg.s.base << 16;
+ region1_size = (mio_boot_reg_cfg.s.size + 1) << 16;
+ if (!mio_boot_reg_cfg.s.en)
+ goto no_cf;
+ is_true_ide = true;
+
+ } else {
+ fdt_nop_property(initial_boot_params, cf, "cavium,true-ide");
+ fdt_nop_property(initial_boot_params, cf, "cavium,dma-engine-handle");
+ if (!is_16bit) {
+ __be32 width = cpu_to_be32(8);
+ fdt_setprop_inplace(initial_boot_params, cf,
+ "cavium,bus-width", &width, sizeof(width));
+ }
+ }
+ new_reg[0] = cpu_to_be32(cs);
+ new_reg[1] = cpu_to_be32(0);
+ new_reg[2] = cpu_to_be32(0x10000);
+ new_reg[3] = cpu_to_be32(cs + 1);
+ new_reg[4] = cpu_to_be32(0);
+ new_reg[5] = cpu_to_be32(0x10000);
+ fdt_setprop_inplace(initial_boot_params, cf,
+ "reg", new_reg, sizeof(new_reg));
+
+ bootbus = fdt_parent_offset(initial_boot_params, cf);
+ if (bootbus < 0)
+ goto no_cf;
+ ranges = fdt_getprop_w(initial_boot_params, bootbus, "ranges", &len);
+ if (!ranges || len < (5 * 8 * sizeof(__be32)))
+ goto no_cf;
+
+ ranges[(cs * 5) + 2] = cpu_to_be32(region_base >> 32);
+ ranges[(cs * 5) + 3] = cpu_to_be32(region_base & 0xffffffff);
+ ranges[(cs * 5) + 4] = cpu_to_be32(region_size);
+ if (is_true_ide) {
+ cs++;
+ ranges[(cs * 5) + 2] = cpu_to_be32(region1_base >> 32);
+ ranges[(cs * 5) + 3] = cpu_to_be32(region1_base & 0xffffffff);
+ ranges[(cs * 5) + 4] = cpu_to_be32(region1_size);
+ }
+ goto end_cf;
+no_cf:
+ fdt_nop_node(initial_boot_params, cf);
+
+end_cf:
+ ;
+ }
+
+ /* 8 char LED */
+ alias_prop = fdt_getprop(initial_boot_params, aliases,
+ "led0", NULL);
+ if (alias_prop) {
+ union cvmx_mio_boot_reg_cfgx mio_boot_reg_cfg;
+ unsigned long base_ptr, region_base, region_size;
+ int cs, bootbus;
+ __be32 new_reg[6];
+ __be32 *ranges;
+ int len;
+ int led = fdt_path_offset(initial_boot_params, alias_prop);
+
+ base_ptr = octeon_bootinfo->led_display_base_addr;
+ if (base_ptr == 0)
+ goto no_led;
+ /* Find CS0 region. */
+ for (cs = 0; cs < 8; cs++) {
+ mio_boot_reg_cfg.u64 = cvmx_read_csr(CVMX_MIO_BOOT_REG_CFGX(cs));
+ 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 (cs > 7)
+ goto no_led;
+
+ new_reg[0] = cpu_to_be32(cs);
+ new_reg[1] = cpu_to_be32(0x20);
+ new_reg[2] = cpu_to_be32(0x20);
+ new_reg[3] = cpu_to_be32(cs);
+ new_reg[4] = cpu_to_be32(0);
+ new_reg[5] = cpu_to_be32(0x20);
+ fdt_setprop_inplace(initial_boot_params, led,
+ "reg", new_reg, sizeof(new_reg));
+
+ bootbus = fdt_parent_offset(initial_boot_params, led);
+ if (bootbus < 0)
+ goto no_led;
+ ranges = fdt_getprop_w(initial_boot_params, bootbus, "ranges", &len);
+ if (!ranges || len < (5 * 8 * sizeof(__be32)))
+ goto no_led;
+
+ ranges[(cs * 5) + 2] = cpu_to_be32(region_base >> 32);
+ ranges[(cs * 5) + 3] = cpu_to_be32(region_base & 0xffffffff);
+ ranges[(cs * 5) + 4] = cpu_to_be32(region_size);
+ goto end_led;
+
+no_led:
+ fdt_nop_node(initial_boot_params, led);
+end_led:
+ ;
+ }
+
+ /* OHCI/UHCI USB */
+ alias_prop = fdt_getprop(initial_boot_params, aliases,
+ "uctl", NULL);
+ if (alias_prop) {
+ int uctl = fdt_path_offset(initial_boot_params, alias_prop);
+
+ if (uctl >= 0 && (!OCTEON_IS_MODEL(OCTEON_CN6XXX) ||
+ octeon_bootinfo->board_type == CVMX_BOARD_TYPE_NIC2E)) {
+ pr_debug("Deleting uctl\n");
+ fdt_nop_node(initial_boot_params, uctl);
+ fdt_nop_property(initial_boot_params, aliases, "uctl");
+ } else if (octeon_bootinfo->board_type == CVMX_BOARD_TYPE_NIC10E ||
+ octeon_bootinfo->board_type == CVMX_BOARD_TYPE_NIC4E) {
+ /* Missing "refclk-type" defaults to crystal. */
+ fdt_nop_property(initial_boot_params, uctl, "refclk-type");
+ }
+ }
+
+ return 0;
+}
+
+static int __init octeon_publish_devices(void)
+{
+ return of_platform_bus_probe(NULL, octeon_ids, NULL);
+}
+device_initcall(octeon_publish_devices);
+
MODULE_AUTHOR("David Daney <ddaney@caviumnetworks.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Platform driver for Octeon SOC");
diff --git a/arch/mips/cavium-octeon/octeon_3xxx.dts b/arch/mips/cavium-octeon/octeon_3xxx.dts
new file mode 100644
index 00000000000..f28b2d0fde2
--- /dev/null
+++ b/arch/mips/cavium-octeon/octeon_3xxx.dts
@@ -0,0 +1,571 @@
+/dts-v1/;
+/*
+ * OCTEON 3XXX, 5XXX, 63XX device tree skeleton.
+ *
+ * This device tree is pruned and patched by early boot code before
+ * use. Because of this, it contains a super-set of the available
+ * devices and properties.
+ */
+/ {
+ compatible = "cavium,octeon-3860";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&ciu>;
+
+ soc@0 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges; /* Direct mapping */
+
+ ciu: interrupt-controller@1070000000000 {
+ compatible = "cavium,octeon-3860-ciu";
+ interrupt-controller;
+ /* Interrupts are specified by two parts:
+ * 1) Controller register (0 or 1)
+ * 2) Bit within the register (0..63)
+ */
+ #interrupt-cells = <2>;
+ reg = <0x10700 0x00000000 0x0 0x7000>;
+ };
+
+ gpio: gpio-controller@1070000000800 {
+ #gpio-cells = <2>;
+ compatible = "cavium,octeon-3860-gpio";
+ reg = <0x10700 0x00000800 0x0 0x100>;
+ gpio-controller;
+ /* Interrupts are specified by two parts:
+ * 1) GPIO pin number (0..15)
+ * 2) Triggering (1 - edge rising
+ * 2 - edge falling
+ * 4 - level active high
+ * 8 - level active low)
+ */
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ /* The GPIO pin connect to 16 consecutive CUI bits */
+ interrupts = <0 16>, <0 17>, <0 18>, <0 19>,
+ <0 20>, <0 21>, <0 22>, <0 23>,
+ <0 24>, <0 25>, <0 26>, <0 27>,
+ <0 28>, <0 29>, <0 30>, <0 31>;
+ };
+
+ smi0: mdio@1180000001800 {
+ compatible = "cavium,octeon-3860-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0x00001800 0x0 0x40>;
+
+ phy0: ethernet-phy@0 {
+ compatible = "marvell,88e1118";
+ marvell,reg-init =
+ /* Fix rx and tx clock transition timing */
+ <2 0x15 0xffcf 0>, /* Reg 2,21 Clear bits 4, 5 */
+ /* Adjust LED drive. */
+ <3 0x11 0 0x442a>, /* Reg 3,17 <- 0442a */
+ /* irq, blink-activity, blink-link */
+ <3 0x10 0 0x0242>; /* Reg 3,16 <- 0x0242 */
+ reg = <0>;
+ };
+
+ phy1: ethernet-phy@1 {
+ compatible = "marvell,88e1118";
+ marvell,reg-init =
+ /* Fix rx and tx clock transition timing */
+ <2 0x15 0xffcf 0>, /* Reg 2,21 Clear bits 4, 5 */
+ /* Adjust LED drive. */
+ <3 0x11 0 0x442a>, /* Reg 3,17 <- 0442a */
+ /* irq, blink-activity, blink-link */
+ <3 0x10 0 0x0242>; /* Reg 3,16 <- 0x0242 */
+ reg = <1>;
+ };
+
+ phy2: ethernet-phy@2 {
+ reg = <2>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy3: ethernet-phy@3 {
+ reg = <3>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy4: ethernet-phy@4 {
+ reg = <4>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy5: ethernet-phy@5 {
+ reg = <5>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+
+ phy6: ethernet-phy@6 {
+ reg = <6>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy7: ethernet-phy@7 {
+ reg = <7>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy8: ethernet-phy@8 {
+ reg = <8>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy9: ethernet-phy@9 {
+ reg = <9>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ };
+
+ smi1: mdio@1180000001900 {
+ compatible = "cavium,octeon-3860-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0x00001900 0x0 0x40>;
+
+ phy100: ethernet-phy@1 {
+ reg = <1>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ interrupt-parent = <&gpio>;
+ interrupts = <12 8>; /* Pin 12, active low */
+ };
+ phy101: ethernet-phy@2 {
+ reg = <2>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ interrupt-parent = <&gpio>;
+ interrupts = <12 8>; /* Pin 12, active low */
+ };
+ phy102: ethernet-phy@3 {
+ reg = <3>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ interrupt-parent = <&gpio>;
+ interrupts = <12 8>; /* Pin 12, active low */
+ };
+ phy103: ethernet-phy@4 {
+ reg = <4>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ interrupt-parent = <&gpio>;
+ interrupts = <12 8>; /* Pin 12, active low */
+ };
+ };
+
+ mix0: ethernet@1070000100000 {
+ compatible = "cavium,octeon-5750-mix";
+ reg = <0x10700 0x00100000 0x0 0x100>, /* MIX */
+ <0x11800 0xE0000000 0x0 0x300>, /* AGL */
+ <0x11800 0xE0000400 0x0 0x400>, /* AGL_SHARED */
+ <0x11800 0xE0002000 0x0 0x8>; /* AGL_PRT_CTL */
+ cell-index = <0>;
+ interrupts = <0 62>, <1 46>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy0>;
+ };
+
+ mix1: ethernet@1070000100800 {
+ compatible = "cavium,octeon-5750-mix";
+ reg = <0x10700 0x00100800 0x0 0x100>, /* MIX */
+ <0x11800 0xE0000800 0x0 0x300>, /* AGL */
+ <0x11800 0xE0000400 0x0 0x400>, /* AGL_SHARED */
+ <0x11800 0xE0002008 0x0 0x8>; /* AGL_PRT_CTL */
+ cell-index = <1>;
+ interrupts = <1 18>, < 1 46>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy1>;
+ };
+
+ pip: pip@11800a0000000 {
+ compatible = "cavium,octeon-3860-pip";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0xa0000000 0x0 0x2000>;
+
+ interface@0 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy2>;
+ cavium,alt-phy-handle = <&phy100>;
+ };
+ ethernet@1 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x1>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy3>;
+ cavium,alt-phy-handle = <&phy101>;
+ };
+ ethernet@2 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x2>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy4>;
+ cavium,alt-phy-handle = <&phy102>;
+ };
+ ethernet@3 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x3>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy5>;
+ cavium,alt-phy-handle = <&phy103>;
+ };
+ ethernet@4 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x4>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@5 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x5>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@6 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x6>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@7 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x7>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@8 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x8>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@9 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x9>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@a {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0xa>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@b {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0xb>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@c {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0xc>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@d {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0xd>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@e {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0xe>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ ethernet@f {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0xf>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ };
+
+ interface@1 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <1>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy6>;
+ };
+ ethernet@1 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x1>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy7>;
+ };
+ ethernet@2 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x2>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy8>;
+ };
+ ethernet@3 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x3>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy9>;
+ };
+ };
+ };
+
+ twsi0: i2c@1180000001000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "cavium,octeon-3860-twsi";
+ reg = <0x11800 0x00001000 0x0 0x200>;
+ interrupts = <0 45>;
+ clock-frequency = <100000>;
+
+ rtc@68 {
+ compatible = "dallas,ds1337";
+ reg = <0x68>;
+ };
+ tmp@4c {
+ compatible = "ti,tmp421";
+ reg = <0x4c>;
+ };
+ };
+
+ twsi1: i2c@1180000001200 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "cavium,octeon-3860-twsi";
+ reg = <0x11800 0x00001200 0x0 0x200>;
+ interrupts = <0 59>;
+ clock-frequency = <100000>;
+ };
+
+ uart0: serial@1180000000800 {
+ compatible = "cavium,octeon-3860-uart","ns16550";
+ reg = <0x11800 0x00000800 0x0 0x400>;
+ clock-frequency = <0>;
+ current-speed = <115200>;
+ reg-shift = <3>;
+ interrupts = <0 34>;
+ };
+
+ uart1: serial@1180000000c00 {
+ compatible = "cavium,octeon-3860-uart","ns16550";
+ reg = <0x11800 0x00000c00 0x0 0x400>;
+ clock-frequency = <0>;
+ current-speed = <115200>;
+ reg-shift = <3>;
+ interrupts = <0 35>;
+ };
+
+ uart2: serial@1180000000400 {
+ compatible = "cavium,octeon-3860-uart","ns16550";
+ reg = <0x11800 0x00000400 0x0 0x400>;
+ clock-frequency = <0>;
+ current-speed = <115200>;
+ reg-shift = <3>;
+ interrupts = <1 16>;
+ };
+
+ bootbus: bootbus@1180000000000 {
+ compatible = "cavium,octeon-3860-bootbus";
+ reg = <0x11800 0x00000000 0x0 0x200>;
+ /* The chip select number and offset */
+ #address-cells = <2>;
+ /* The size of the chip select region */
+ #size-cells = <1>;
+ ranges = <0 0 0x0 0x1f400000 0xc00000>,
+ <1 0 0x10000 0x30000000 0>,
+ <2 0 0x10000 0x40000000 0>,
+ <3 0 0x10000 0x50000000 0>,
+ <4 0 0x0 0x1d020000 0x10000>,
+ <5 0 0x0 0x1d040000 0x10000>,
+ <6 0 0x0 0x1d050000 0x10000>,
+ <7 0 0x10000 0x90000000 0>;
+
+ cavium,cs-config@0 {
+ compatible = "cavium,octeon-3860-bootbus-config";
+ cavium,cs-index = <0>;
+ cavium,t-adr = <20>;
+ cavium,t-ce = <60>;
+ cavium,t-oe = <60>;
+ cavium,t-we = <45>;
+ cavium,t-rd-hld = <35>;
+ cavium,t-wr-hld = <45>;
+ cavium,t-pause = <0>;
+ cavium,t-wait = <0>;
+ cavium,t-page = <35>;
+ cavium,t-rd-dly = <0>;
+
+ cavium,pages = <0>;
+ cavium,bus-width = <8>;
+ };
+ cavium,cs-config@4 {
+ compatible = "cavium,octeon-3860-bootbus-config";
+ cavium,cs-index = <4>;
+ cavium,t-adr = <320>;
+ cavium,t-ce = <320>;
+ cavium,t-oe = <320>;
+ cavium,t-we = <320>;
+ cavium,t-rd-hld = <320>;
+ cavium,t-wr-hld = <320>;
+ cavium,t-pause = <320>;
+ cavium,t-wait = <320>;
+ cavium,t-page = <320>;
+ cavium,t-rd-dly = <0>;
+
+ cavium,pages = <0>;
+ cavium,bus-width = <8>;
+ };
+ cavium,cs-config@5 {
+ compatible = "cavium,octeon-3860-bootbus-config";
+ cavium,cs-index = <5>;
+ cavium,t-adr = <5>;
+ cavium,t-ce = <300>;
+ cavium,t-oe = <125>;
+ cavium,t-we = <150>;
+ cavium,t-rd-hld = <100>;
+ cavium,t-wr-hld = <30>;
+ cavium,t-pause = <0>;
+ cavium,t-wait = <30>;
+ cavium,t-page = <320>;
+ cavium,t-rd-dly = <0>;
+
+ cavium,pages = <0>;
+ cavium,bus-width = <16>;
+ };
+ cavium,cs-config@6 {
+ compatible = "cavium,octeon-3860-bootbus-config";
+ cavium,cs-index = <6>;
+ cavium,t-adr = <5>;
+ cavium,t-ce = <300>;
+ cavium,t-oe = <270>;
+ cavium,t-we = <150>;
+ cavium,t-rd-hld = <100>;
+ cavium,t-wr-hld = <70>;
+ cavium,t-pause = <0>;
+ cavium,t-wait = <0>;
+ cavium,t-page = <320>;
+ cavium,t-rd-dly = <0>;
+
+ cavium,pages = <0>;
+ cavium,wait-mode;
+ cavium,bus-width = <16>;
+ };
+
+ flash0: nor@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x800000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+ };
+
+ led0: led-display@4,0 {
+ compatible = "avago,hdsp-253x";
+ reg = <4 0x20 0x20>, <4 0 0x20>;
+ };
+
+ cf0: compact-flash@5,0 {
+ compatible = "cavium,ebt3000-compact-flash";
+ reg = <5 0 0x10000>, <6 0 0x10000>;
+ cavium,bus-width = <16>;
+ cavium,true-ide;
+ cavium,dma-engine-handle = <&dma0>;
+ };
+ };
+
+ dma0: dma-engine@1180000000100 {
+ compatible = "cavium,octeon-5750-bootbus-dma";
+ reg = <0x11800 0x00000100 0x0 0x8>;
+ interrupts = <0 63>;
+ };
+ dma1: dma-engine@1180000000108 {
+ compatible = "cavium,octeon-5750-bootbus-dma";
+ reg = <0x11800 0x00000108 0x0 0x8>;
+ interrupts = <0 63>;
+ };
+
+ uctl: uctl@118006f000000 {
+ compatible = "cavium,octeon-6335-uctl";
+ reg = <0x11800 0x6f000000 0x0 0x100>;
+ ranges; /* Direct mapping */
+ #address-cells = <2>;
+ #size-cells = <2>;
+ /* 12MHz, 24MHz and 48MHz allowed */
+ refclk-frequency = <12000000>;
+ /* Either "crystal" or "external" */
+ refclk-type = "crystal";
+
+ ehci@16f0000000000 {
+ compatible = "cavium,octeon-6335-ehci","usb-ehci";
+ reg = <0x16f00 0x00000000 0x0 0x100>;
+ interrupts = <0 56>;
+ big-endian-regs;
+ };
+ ohci@16f0000000400 {
+ compatible = "cavium,octeon-6335-ohci","usb-ohci";
+ reg = <0x16f00 0x00000400 0x0 0x100>;
+ interrupts = <0 56>;
+ big-endian-regs;
+ };
+ };
+ };
+
+ aliases {
+ mix0 = &mix0;
+ mix1 = &mix1;
+ pip = &pip;
+ smi0 = &smi0;
+ smi1 = &smi1;
+ twsi0 = &twsi0;
+ twsi1 = &twsi1;
+ uart0 = &uart0;
+ uart1 = &uart1;
+ uart2 = &uart2;
+ flash0 = &flash0;
+ cf0 = &cf0;
+ uctl = &uctl;
+ led0 = &led0;
+ };
+ };
diff --git a/arch/mips/cavium-octeon/octeon_68xx.dts b/arch/mips/cavium-octeon/octeon_68xx.dts
new file mode 100644
index 00000000000..1839468932b
--- /dev/null
+++ b/arch/mips/cavium-octeon/octeon_68xx.dts
@@ -0,0 +1,625 @@
+/dts-v1/;
+/*
+ * OCTEON 68XX device tree skeleton.
+ *
+ * This device tree is pruned and patched by early boot code before
+ * use. Because of this, it contains a super-set of the available
+ * devices and properties.
+ */
+/ {
+ compatible = "cavium,octeon-6880";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ interrupt-parent = <&ciu2>;
+
+ soc@0 {
+ compatible = "simple-bus";
+ #address-cells = <2>;
+ #size-cells = <2>;
+ ranges; /* Direct mapping */
+
+ ciu2: interrupt-controller@1070100000000 {
+ compatible = "cavium,octeon-6880-ciu2";
+ interrupt-controller;
+ /* Interrupts are specified by two parts:
+ * 1) Controller register (0 or 7)
+ * 2) Bit within the register (0..63)
+ */
+ #address-cells = <0>;
+ #interrupt-cells = <2>;
+ reg = <0x10701 0x00000000 0x0 0x4000000>;
+ };
+
+ gpio: gpio-controller@1070000000800 {
+ #gpio-cells = <2>;
+ compatible = "cavium,octeon-3860-gpio";
+ reg = <0x10700 0x00000800 0x0 0x100>;
+ gpio-controller;
+ /* Interrupts are specified by two parts:
+ * 1) GPIO pin number (0..15)
+ * 2) Triggering (1 - edge rising
+ * 2 - edge falling
+ * 4 - level active high
+ * 8 - level active low)
+ */
+ interrupt-controller;
+ #interrupt-cells = <2>;
+ /* The GPIO pins connect to 16 consecutive CUI bits */
+ interrupts = <7 0>, <7 1>, <7 2>, <7 3>,
+ <7 4>, <7 5>, <7 6>, <7 7>,
+ <7 8>, <7 9>, <7 10>, <7 11>,
+ <7 12>, <7 13>, <7 14>, <7 15>;
+ };
+
+ smi0: mdio@1180000003800 {
+ compatible = "cavium,octeon-3860-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0x00003800 0x0 0x40>;
+
+ phy0: ethernet-phy@6 {
+ compatible = "marvell,88e1118";
+ marvell,reg-init =
+ /* Fix rx and tx clock transition timing */
+ <2 0x15 0xffcf 0>, /* Reg 2,21 Clear bits 4, 5 */
+ /* Adjust LED drive. */
+ <3 0x11 0 0x442a>, /* Reg 3,17 <- 0442a */
+ /* irq, blink-activity, blink-link */
+ <3 0x10 0 0x0242>; /* Reg 3,16 <- 0x0242 */
+ reg = <6>;
+ };
+
+ phy1: ethernet-phy@1 {
+ cavium,qlm-trim = "4,sgmii";
+ reg = <1>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy2: ethernet-phy@2 {
+ cavium,qlm-trim = "4,sgmii";
+ reg = <2>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy3: ethernet-phy@3 {
+ cavium,qlm-trim = "4,sgmii";
+ reg = <3>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy4: ethernet-phy@4 {
+ cavium,qlm-trim = "4,sgmii";
+ reg = <4>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ };
+
+ smi1: mdio@1180000003880 {
+ compatible = "cavium,octeon-3860-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0x00003880 0x0 0x40>;
+
+ phy41: ethernet-phy@1 {
+ cavium,qlm-trim = "0,sgmii";
+ reg = <1>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy42: ethernet-phy@2 {
+ cavium,qlm-trim = "0,sgmii";
+ reg = <2>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy43: ethernet-phy@3 {
+ cavium,qlm-trim = "0,sgmii";
+ reg = <3>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy44: ethernet-phy@4 {
+ cavium,qlm-trim = "0,sgmii";
+ reg = <4>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ };
+
+ smi2: mdio@1180000003900 {
+ compatible = "cavium,octeon-3860-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0x00003900 0x0 0x40>;
+
+ phy21: ethernet-phy@1 {
+ cavium,qlm-trim = "2,sgmii";
+ reg = <1>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy22: ethernet-phy@2 {
+ cavium,qlm-trim = "2,sgmii";
+ reg = <2>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy23: ethernet-phy@3 {
+ cavium,qlm-trim = "2,sgmii";
+ reg = <3>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy24: ethernet-phy@4 {
+ cavium,qlm-trim = "2,sgmii";
+ reg = <4>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ };
+
+ smi3: mdio@1180000003980 {
+ compatible = "cavium,octeon-3860-mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0x00003980 0x0 0x40>;
+
+ phy11: ethernet-phy@1 {
+ cavium,qlm-trim = "3,sgmii";
+ reg = <1>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy12: ethernet-phy@2 {
+ cavium,qlm-trim = "3,sgmii";
+ reg = <2>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy13: ethernet-phy@3 {
+ cavium,qlm-trim = "3,sgmii";
+ reg = <3>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ phy14: ethernet-phy@4 {
+ cavium,qlm-trim = "3,sgmii";
+ reg = <4>;
+ compatible = "marvell,88e1149r";
+ marvell,reg-init = <3 0x10 0 0x5777>,
+ <3 0x11 0 0x00aa>,
+ <3 0x12 0 0x4105>,
+ <3 0x13 0 0x0a60>;
+ };
+ };
+
+ mix0: ethernet@1070000100000 {
+ compatible = "cavium,octeon-5750-mix";
+ reg = <0x10700 0x00100000 0x0 0x100>, /* MIX */
+ <0x11800 0xE0000000 0x0 0x300>, /* AGL */
+ <0x11800 0xE0000400 0x0 0x400>, /* AGL_SHARED */
+ <0x11800 0xE0002000 0x0 0x8>; /* AGL_PRT_CTL */
+ cell-index = <0>;
+ interrupts = <6 40>, <6 32>;
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy0>;
+ };
+
+ pip: pip@11800a0000000 {
+ compatible = "cavium,octeon-3860-pip";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x11800 0xa0000000 0x0 0x2000>;
+
+ interface@4 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x4>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy1>;
+ };
+ ethernet@1 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x1>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy2>;
+ };
+ ethernet@2 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x2>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy3>;
+ };
+ ethernet@3 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x3>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy4>;
+ };
+ };
+
+ interface@3 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x3>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy11>;
+ };
+ ethernet@1 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x1>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy12>;
+ };
+ ethernet@2 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x2>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy13>;
+ };
+ ethernet@3 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x3>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy14>;
+ };
+ };
+
+ interface@2 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy21>;
+ };
+ ethernet@1 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x1>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy22>;
+ };
+ ethernet@2 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x2>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy23>;
+ };
+ ethernet@3 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x3>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy24>;
+ };
+ };
+
+ interface@1 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x1>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ };
+ };
+
+ interface@0 {
+ compatible = "cavium,octeon-3860-pip-interface";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0>; /* interface */
+
+ ethernet@0 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x0>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy41>;
+ };
+ ethernet@1 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x1>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy42>;
+ };
+ ethernet@2 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x2>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy43>;
+ };
+ ethernet@3 {
+ compatible = "cavium,octeon-3860-pip-port";
+ reg = <0x3>; /* Port */
+ local-mac-address = [ 00 00 00 00 00 00 ];
+ phy-handle = <&phy44>;
+ };
+ };
+ };
+
+ twsi0: i2c@1180000001000 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "cavium,octeon-3860-twsi";
+ reg = <0x11800 0x00001000 0x0 0x200>;
+ interrupts = <3 32>;
+ clock-frequency = <100000>;
+
+ rtc@68 {
+ compatible = "dallas,ds1337";
+ reg = <0x68>;
+ };
+ tmp@4c {
+ compatible = "ti,tmp421";
+ reg = <0x4c>;
+ };
+ };
+
+ twsi1: i2c@1180000001200 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "cavium,octeon-3860-twsi";
+ reg = <0x11800 0x00001200 0x0 0x200>;
+ interrupts = <3 33>;
+ clock-frequency = <100000>;
+ };
+
+ uart0: serial@1180000000800 {
+ compatible = "cavium,octeon-3860-uart","ns16550";
+ reg = <0x11800 0x00000800 0x0 0x400>;
+ clock-frequency = <0>;
+ current-speed = <115200>;
+ reg-shift = <3>;
+ interrupts = <3 36>;
+ };
+
+ uart1: serial@1180000000c00 {
+ compatible = "cavium,octeon-3860-uart","ns16550";
+ reg = <0x11800 0x00000c00 0x0 0x400>;
+ clock-frequency = <0>;
+ current-speed = <115200>;
+ reg-shift = <3>;
+ interrupts = <3 37>;
+ };
+
+ bootbus: bootbus@1180000000000 {
+ compatible = "cavium,octeon-3860-bootbus";
+ reg = <0x11800 0x00000000 0x0 0x200>;
+ /* The chip select number and offset */
+ #address-cells = <2>;
+ /* The size of the chip select region */
+ #size-cells = <1>;
+ ranges = <0 0 0 0x1f400000 0xc00000>,
+ <1 0 0x10000 0x30000000 0>,
+ <2 0 0x10000 0x40000000 0>,
+ <3 0 0x10000 0x50000000 0>,
+ <4 0 0 0x1d020000 0x10000>,
+ <5 0 0 0x1d040000 0x10000>,
+ <6 0 0 0x1d050000 0x10000>,
+ <7 0 0x10000 0x90000000 0>;
+
+ cavium,cs-config@0 {
+ compatible = "cavium,octeon-3860-bootbus-config";
+ cavium,cs-index = <0>;
+ cavium,t-adr = <10>;
+ cavium,t-ce = <50>;
+ cavium,t-oe = <50>;
+ cavium,t-we = <35>;
+ cavium,t-rd-hld = <25>;
+ cavium,t-wr-hld = <35>;
+ cavium,t-pause = <0>;
+ cavium,t-wait = <300>;
+ cavium,t-page = <25>;
+ cavium,t-rd-dly = <0>;
+
+ cavium,pages = <0>;
+ cavium,bus-width = <8>;
+ };
+ cavium,cs-config@4 {
+ compatible = "cavium,octeon-3860-bootbus-config";
+ cavium,cs-index = <4>;
+ cavium,t-adr = <320>;
+ cavium,t-ce = <320>;
+ cavium,t-oe = <320>;
+ cavium,t-we = <320>;
+ cavium,t-rd-hld = <320>;
+ cavium,t-wr-hld = <320>;
+ cavium,t-pause = <320>;
+ cavium,t-wait = <320>;
+ cavium,t-page = <320>;
+ cavium,t-rd-dly = <0>;
+
+ cavium,pages = <0>;
+ cavium,bus-width = <8>;
+ };
+ cavium,cs-config@5 {
+ compatible = "cavium,octeon-3860-bootbus-config";
+ cavium,cs-index = <5>;
+ cavium,t-adr = <0>;
+ cavium,t-ce = <300>;
+ cavium,t-oe = <125>;
+ cavium,t-we = <150>;
+ cavium,t-rd-hld = <100>;
+ cavium,t-wr-hld = <300>;
+ cavium,t-pause = <0>;
+ cavium,t-wait = <300>;
+ cavium,t-page = <310>;
+ cavium,t-rd-dly = <0>;
+
+ cavium,pages = <0>;
+ cavium,bus-width = <16>;
+ };
+ cavium,cs-config@6 {
+ compatible = "cavium,octeon-3860-bootbus-config";
+ cavium,cs-index = <6>;
+ cavium,t-adr = <0>;
+ cavium,t-ce = <30>;
+ cavium,t-oe = <125>;
+ cavium,t-we = <150>;
+ cavium,t-rd-hld = <100>;
+ cavium,t-wr-hld = <30>;
+ cavium,t-pause = <0>;
+ cavium,t-wait = <30>;
+ cavium,t-page = <310>;
+ cavium,t-rd-dly = <0>;
+
+ cavium,pages = <0>;
+ cavium,wait-mode;
+ cavium,bus-width = <16>;
+ };
+
+ flash0: nor@0,0 {
+ compatible = "cfi-flash";
+ reg = <0 0 0x800000>;
+ #address-cells = <1>;
+ #size-cells = <1>;
+
+ partition@0 {
+ label = "bootloader";
+ reg = <0 0x200000>;
+ read-only;
+ };
+ partition@200000 {
+ label = "kernel";
+ reg = <0x200000 0x200000>;
+ };
+ partition@400000 {
+ label = "cramfs";
+ reg = <0x400000 0x3fe000>;
+ };
+ partition@7fe000 {
+ label = "environment";
+ reg = <0x7fe000 0x2000>;
+ read-only;
+ };
+ };
+
+ led0: led-display@4,0 {
+ compatible = "avago,hdsp-253x";
+ reg = <4 0x20 0x20>, <4 0 0x20>;
+ };
+
+ compact-flash@5,0 {
+ compatible = "cavium,ebt3000-compact-flash";
+ reg = <5 0 0x10000>, <6 0 0x10000>;
+ cavium,bus-width = <16>;
+ cavium,true-ide;
+ cavium,dma-engine-handle = <&dma0>;
+ };
+ };
+
+ dma0: dma-engine@1180000000100 {
+ compatible = "cavium,octeon-5750-bootbus-dma";
+ reg = <0x11800 0x00000100 0x0 0x8>;
+ interrupts = <0 63>;
+ };
+ dma1: dma-engine@1180000000108 {
+ compatible = "cavium,octeon-5750-bootbus-dma";
+ reg = <0x11800 0x00000108 0x0 0x8>;
+ interrupts = <0 63>;
+ };
+
+ uctl: uctl@118006f000000 {
+ compatible = "cavium,octeon-6335-uctl";
+ reg = <0x11800 0x6f000000 0x0 0x100>;
+ ranges; /* Direct mapping */
+ #address-cells = <2>;
+ #size-cells = <2>;
+ /* 12MHz, 24MHz and 48MHz allowed */
+ refclk-frequency = <12000000>;
+ /* Either "crystal" or "external" */
+ refclk-type = "crystal";
+
+ ehci@16f0000000000 {
+ compatible = "cavium,octeon-6335-ehci","usb-ehci";
+ reg = <0x16f00 0x00000000 0x0 0x100>;
+ interrupts = <3 44>;
+ big-endian-regs;
+ };
+ ohci@16f0000000400 {
+ compatible = "cavium,octeon-6335-ohci","usb-ohci";
+ reg = <0x16f00 0x00000400 0x0 0x100>;
+ interrupts = <3 44>;
+ big-endian-regs;
+ };
+ };
+ };
+
+ aliases {
+ mix0 = &mix0;
+ pip = &pip;
+ smi0 = &smi0;
+ smi1 = &smi1;
+ smi2 = &smi2;
+ smi3 = &smi3;
+ twsi0 = &twsi0;
+ twsi1 = &twsi1;
+ uart0 = &uart0;
+ uart1 = &uart1;
+ uctl = &uctl;
+ led0 = &led0;
+ flash0 = &flash0;
+ };
+ };
diff --git a/arch/mips/cavium-octeon/serial.c b/arch/mips/cavium-octeon/serial.c
index 057f0ae88c9..138b2216b4f 100644
--- a/arch/mips/cavium-octeon/serial.c
+++ b/arch/mips/cavium-octeon/serial.c
@@ -43,95 +43,67 @@ void octeon_serial_out(struct uart_port *up, int offset, int value)
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)
+static int __devinit octeon_serial_probe(struct platform_device *pdev)
{
- 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 */
+ int irq, res;
+ struct resource *res_mem;
+ struct uart_port port;
+
+ /* All adaptors have an irq. */
+ irq = platform_get_irq(pdev, 0);
+ if (irq < 0)
+ return irq;
+
+ memset(&port, 0, sizeof(port));
+
+ port.flags = ASYNC_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE;
+ port.type = PORT_OCTEON;
+ port.iotype = UPIO_MEM;
+ port.regshift = 3;
+ port.dev = &pdev->dev;
+
if (octeon_is_simulation())
/* Make simulator output fast*/
- p->uartclk = 115200 * 16;
+ port.uartclk = 115200 * 16;
else
- p->uartclk = octeon_get_io_clock_rate();
- p->serial_in = octeon_serial_in;
- p->serial_out = octeon_serial_out;
-}
+ port.uartclk = octeon_get_io_clock_rate();
-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++;
- }
+ port.serial_in = octeon_serial_in;
+ port.serial_out = octeon_serial_out;
+ port.irq = irq;
- 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++;
+ res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res_mem == NULL) {
+ dev_err(&pdev->dev, "found no memory resource\n");
+ return -ENXIO;
}
+ port.mapbase = res_mem->start;
+ port.membase = ioremap(res_mem->start, resource_size(res_mem));
- BUG_ON(p > &octeon_uart8250_data[OCTEON_MAX_UARTS]);
+ res = serial8250_register_port(&port);
- return platform_device_register(&octeon_uart8250_device);
+ return res >= 0 ? 0 : res;
}
-device_initcall(octeon_serial_init);
+static struct of_device_id octeon_serial_match[] = {
+ {
+ .compatible = "cavium,octeon-3860-uart",
+ },
+ {},
+};
+MODULE_DEVICE_TABLE(of, octeon_serial_match);
+
+static struct platform_driver octeon_serial_driver = {
+ .probe = octeon_serial_probe,
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = "octeon_serial",
+ .of_match_table = octeon_serial_match,
+ },
+};
+
+static int __init octeon_serial_init(void)
+{
+ return platform_driver_register(&octeon_serial_driver);
+}
+late_initcall(octeon_serial_init);
diff --git a/arch/mips/cavium-octeon/setup.c b/arch/mips/cavium-octeon/setup.c
index 260dc247c05..919b0fb7bb1 100644
--- a/arch/mips/cavium-octeon/setup.c
+++ b/arch/mips/cavium-octeon/setup.c
@@ -21,6 +21,8 @@
#include <linux/platform_device.h>
#include <linux/serial_core.h>
#include <linux/serial_8250.h>
+#include <linux/of_fdt.h>
+#include <linux/libfdt.h>
#include <asm/processor.h>
#include <asm/reboot.h>
@@ -775,3 +777,46 @@ void prom_free_prom_memory(void)
}
#endif
}
+
+int octeon_prune_device_tree(void);
+
+extern const char __dtb_octeon_3xxx_begin;
+extern const char __dtb_octeon_3xxx_end;
+extern const char __dtb_octeon_68xx_begin;
+extern const char __dtb_octeon_68xx_end;
+void __init device_tree_init(void)
+{
+ int dt_size;
+ struct boot_param_header *fdt;
+ bool do_prune;
+
+ if (octeon_bootinfo->minor_version >= 3 && octeon_bootinfo->fdt_addr) {
+ fdt = phys_to_virt(octeon_bootinfo->fdt_addr);
+ if (fdt_check_header(fdt))
+ panic("Corrupt Device Tree passed to kernel.");
+ dt_size = be32_to_cpu(fdt->totalsize);
+ do_prune = false;
+ } else if (OCTEON_IS_MODEL(OCTEON_CN68XX)) {
+ fdt = (struct boot_param_header *)&__dtb_octeon_68xx_begin;
+ dt_size = &__dtb_octeon_68xx_end - &__dtb_octeon_68xx_begin;
+ do_prune = true;
+ } else {
+ fdt = (struct boot_param_header *)&__dtb_octeon_3xxx_begin;
+ dt_size = &__dtb_octeon_3xxx_end - &__dtb_octeon_3xxx_begin;
+ do_prune = true;
+ }
+
+ /* Copy the default tree from init memory. */
+ initial_boot_params = early_init_dt_alloc_memory_arch(dt_size, 8);
+ if (initial_boot_params == NULL)
+ panic("Could not allocate initial_boot_params\n");
+ memcpy(initial_boot_params, fdt, dt_size);
+
+ if (do_prune) {
+ octeon_prune_device_tree();
+ pr_info("Using internal Device Tree.\n");
+ } else {
+ pr_info("Using passed Device Tree.\n");
+ }
+ unflatten_device_tree();
+}
diff --git a/arch/mips/configs/ls1b_defconfig b/arch/mips/configs/ls1b_defconfig
new file mode 100644
index 00000000000..80cff8bea8e
--- /dev/null
+++ b/arch/mips/configs/ls1b_defconfig
@@ -0,0 +1,109 @@
+CONFIG_MACH_LOONGSON1=y
+CONFIG_PREEMPT=y
+# CONFIG_SECCOMP is not set
+CONFIG_EXPERIMENTAL=y
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_BSD_PROCESS_ACCT=y
+CONFIG_BSD_PROCESS_ACCT_V3=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_IKCONFIG=y
+CONFIG_IKCONFIG_PROC=y
+CONFIG_LOG_BUF_SHIFT=16
+CONFIG_NAMESPACES=y
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+CONFIG_EXPERT=y
+CONFIG_PERF_EVENTS=y
+# CONFIG_COMPAT_BRK is not set
+CONFIG_MODULES=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODVERSIONS=y
+# CONFIG_LBDAF is not set
+# CONFIG_BLK_DEV_BSG is not set
+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
+# CONFIG_SUSPEND is not set
+CONFIG_NET=y
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+CONFIG_INET=y
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_SYN_COOKIES=y
+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
+# CONFIG_INET_XFRM_MODE_TUNNEL is not set
+# CONFIG_INET_XFRM_MODE_BEET is not set
+# CONFIG_INET_DIAG is not set
+# CONFIG_IPV6 is not set
+# CONFIG_WIRELESS is not set
+CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
+CONFIG_DEVTMPFS=y
+CONFIG_DEVTMPFS_MOUNT=y
+# CONFIG_STANDALONE is not set
+CONFIG_BLK_DEV_LOOP=y
+CONFIG_SCSI=m
+# CONFIG_SCSI_PROC_FS is not set
+CONFIG_BLK_DEV_SD=m
+# CONFIG_SCSI_LOWLEVEL is not set
+CONFIG_NETDEVICES=y
+# CONFIG_NET_VENDOR_BROADCOM is not set
+# CONFIG_NET_VENDOR_CHELSIO is not set
+# CONFIG_NET_VENDOR_INTEL is not set
+# CONFIG_NET_VENDOR_MARVELL is not set
+# CONFIG_NET_VENDOR_MICREL is not set
+# CONFIG_NET_VENDOR_NATSEMI is not set
+# CONFIG_NET_VENDOR_SEEQ is not set
+# CONFIG_NET_VENDOR_SMSC is not set
+CONFIG_STMMAC_ETH=y
+CONFIG_STMMAC_DA=y
+# CONFIG_NET_VENDOR_WIZNET is not set
+# CONFIG_WLAN is not set
+CONFIG_INPUT_EVDEV=y
+# CONFIG_INPUT_KEYBOARD is not set
+# CONFIG_INPUT_MOUSE is not set
+# CONFIG_SERIO is not set
+CONFIG_VT_HW_CONSOLE_BINDING=y
+CONFIG_LEGACY_PTY_COUNT=8
+# CONFIG_DEVKMEM is not set
+CONFIG_SERIAL_8250=y
+CONFIG_SERIAL_8250_CONSOLE=y
+# CONFIG_HW_RANDOM is not set
+# CONFIG_HWMON is not set
+# CONFIG_VGA_CONSOLE is not set
+CONFIG_USB_HID=m
+CONFIG_HID_GENERIC=m
+CONFIG_USB=y
+CONFIG_USB_ANNOUNCE_NEW_DEVICES=y
+CONFIG_USB_EHCI_HCD=y
+# CONFIG_USB_EHCI_TT_NEWSCHED is not set
+CONFIG_USB_STORAGE=m
+CONFIG_USB_SERIAL=m
+CONFIG_USB_SERIAL_PL2303=m
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_LOONGSON1=y
+# CONFIG_IOMMU_SUPPORT is not set
+CONFIG_EXT2_FS=y
+CONFIG_EXT2_FS_XATTR=y
+CONFIG_EXT2_FS_POSIX_ACL=y
+CONFIG_EXT2_FS_SECURITY=y
+CONFIG_EXT3_FS=y
+CONFIG_EXT3_FS_POSIX_ACL=y
+CONFIG_EXT3_FS_SECURITY=y
+# CONFIG_DNOTIFY is not set
+CONFIG_VFAT_FS=y
+CONFIG_PROC_KCORE=y
+CONFIG_TMPFS=y
+CONFIG_TMPFS_POSIX_ACL=y
+# CONFIG_MISC_FILESYSTEMS is not set
+CONFIG_NFS_FS=y
+CONFIG_ROOT_NFS=y
+CONFIG_NLS_CODEPAGE_437=m
+CONFIG_NLS_ISO8859_1=m
+# CONFIG_ENABLE_WARN_DEPRECATED is not set
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_MAGIC_SYSRQ=y
+# CONFIG_SCHED_DEBUG is not set
+# CONFIG_DEBUG_PREEMPT is not set
+# CONFIG_FTRACE is not set
+# CONFIG_EARLY_PRINTK is not set
diff --git a/arch/mips/configs/nlm_xlr_defconfig b/arch/mips/configs/nlm_xlr_defconfig
index d0b857d98c9..138f698d7c0 100644
--- a/arch/mips/configs/nlm_xlr_defconfig
+++ b/arch/mips/configs/nlm_xlr_defconfig
@@ -367,6 +367,10 @@ CONFIG_SERIAL_8250_RSA=y
CONFIG_HW_RANDOM=y
CONFIG_HW_RANDOM_TIMERIOMEM=m
CONFIG_RAW_DRIVER=m
+CONFIG_I2C=y
+CONFIG_I2C_XLR=y
+CONFIG_RTC_CLASS=y
+CONFIG_RTC_DRV_DS1374=y
# CONFIG_HWMON is not set
# CONFIG_VGA_CONSOLE is not set
# CONFIG_HID_SUPPORT is not set
diff --git a/arch/mips/dec/prom/memory.c b/arch/mips/dec/prom/memory.c
index e95ff3054ff..8c62316f22f 100644
--- a/arch/mips/dec/prom/memory.c
+++ b/arch/mips/dec/prom/memory.c
@@ -101,7 +101,7 @@ void __init prom_free_prom_memory(void)
* the first page reserved for the exception handlers.
*/
-#if defined(CONFIG_DECLANCE) || defined(CONFIG_DECLANCE_MODULE)
+#if IS_ENABLED(CONFIG_DECLANCE)
/*
* Leave 128 KB reserved for Lance memory for
* IOASIC DECstations.
diff --git a/arch/mips/include/asm/clock.h b/arch/mips/include/asm/clock.h
index 83894aa7932..c9456e7a728 100644
--- a/arch/mips/include/asm/clock.h
+++ b/arch/mips/include/asm/clock.h
@@ -50,15 +50,4 @@ void clk_recalc_rate(struct clk *);
int clk_register(struct clk *);
void clk_unregister(struct clk *);
-/* the exported API, in addition to clk_set_rate */
-/**
- * clk_set_rate_ex - set the clock rate for a clock source, with additional parameter
- * @clk: clock source
- * @rate: desired clock rate in Hz
- * @algo_id: algorithm id to be passed down to ops->set_rate
- *
- * Returns success (0) or negative errno.
- */
-int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id);
-
#endif /* __ASM_MIPS_CLOCK_H */
diff --git a/arch/mips/include/asm/cpu.h b/arch/mips/include/asm/cpu.h
index 95e40c1e8ed..f21b7c04e95 100644
--- a/arch/mips/include/asm/cpu.h
+++ b/arch/mips/include/asm/cpu.h
@@ -197,6 +197,7 @@
#define PRID_REV_VR4181A 0x0070 /* Same as VR4122 */
#define PRID_REV_VR4130 0x0080
#define PRID_REV_34K_V1_0_2 0x0022
+#define PRID_REV_LOONGSON1B 0x0020
#define PRID_REV_LOONGSON2E 0x0002
#define PRID_REV_LOONGSON2F 0x0003
@@ -261,7 +262,7 @@ enum cpu_type_enum {
*/
CPU_4KC, CPU_4KEC, CPU_4KSC, CPU_24K, CPU_34K, CPU_1004K, CPU_74K,
CPU_ALCHEMY, CPU_PR4450, CPU_BMIPS32, CPU_BMIPS3300, CPU_BMIPS4350,
- CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_M14KC,
+ CPU_BMIPS4380, CPU_BMIPS5000, CPU_JZRISC, CPU_LOONGSON1, CPU_M14KC,
/*
* MIPS64 class processors
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
index 5b8d15bb5fe..e104ddb694a 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_cpu.h
@@ -9,6 +9,7 @@
* compile time if only one CPU support is enabled (idea stolen from
* arm mach-types)
*/
+#define BCM6328_CPU_ID 0x6328
#define BCM6338_CPU_ID 0x6338
#define BCM6345_CPU_ID 0x6345
#define BCM6348_CPU_ID 0x6348
@@ -20,6 +21,19 @@ u16 __bcm63xx_get_cpu_id(void);
u16 bcm63xx_get_cpu_rev(void);
unsigned int bcm63xx_get_cpu_freq(void);
+#ifdef CONFIG_BCM63XX_CPU_6328
+# ifdef bcm63xx_get_cpu_id
+# undef bcm63xx_get_cpu_id
+# define bcm63xx_get_cpu_id() __bcm63xx_get_cpu_id()
+# define BCMCPU_RUNTIME_DETECT
+# else
+# define bcm63xx_get_cpu_id() BCM6328_CPU_ID
+# endif
+# define BCMCPU_IS_6328() (bcm63xx_get_cpu_id() == BCM6328_CPU_ID)
+#else
+# define BCMCPU_IS_6328() (0)
+#endif
+
#ifdef CONFIG_BCM63XX_CPU_6338
# ifdef bcm63xx_get_cpu_id
# undef bcm63xx_get_cpu_id
@@ -102,13 +116,13 @@ enum bcm63xx_regs_set {
RSET_UART1,
RSET_GPIO,
RSET_SPI,
- RSET_SPI2,
RSET_UDC0,
RSET_OHCI0,
RSET_OHCI_PRIV,
RSET_USBH_PRIV,
RSET_MPI,
RSET_PCMCIA,
+ RSET_PCIE,
RSET_DSL,
RSET_ENET0,
RSET_ENET1,
@@ -130,11 +144,17 @@ enum bcm63xx_regs_set {
RSET_PCMDMA,
RSET_PCMDMAC,
RSET_PCMDMAS,
+ RSET_RNG,
+ RSET_MISC
};
#define RSET_DSL_LMEM_SIZE (64 * 1024 * 4)
#define RSET_DSL_SIZE 4096
#define RSET_WDT_SIZE 12
+#define BCM_6338_RSET_SPI_SIZE 64
+#define BCM_6348_RSET_SPI_SIZE 64
+#define BCM_6358_RSET_SPI_SIZE 1804
+#define BCM_6368_RSET_SPI_SIZE 1804
#define RSET_ENET_SIZE 2048
#define RSET_ENETDMA_SIZE 2048
#define RSET_ENETSW_SIZE 65536
@@ -149,8 +169,53 @@ enum bcm63xx_regs_set {
#define RSET_XTMDMA_SIZE 256
#define RSET_XTMDMAC_SIZE(chans) (16 * (chans))
#define RSET_XTMDMAS_SIZE(chans) (16 * (chans))
+#define RSET_RNG_SIZE 20
/*
+ * 6328 register sets base address
+ */
+#define BCM_6328_DSL_LMEM_BASE (0xdeadbeef)
+#define BCM_6328_PERF_BASE (0xb0000000)
+#define BCM_6328_TIMER_BASE (0xb0000040)
+#define BCM_6328_WDT_BASE (0xb000005c)
+#define BCM_6328_UART0_BASE (0xb0000100)
+#define BCM_6328_UART1_BASE (0xb0000120)
+#define BCM_6328_GPIO_BASE (0xb0000080)
+#define BCM_6328_SPI_BASE (0xdeadbeef)
+#define BCM_6328_UDC0_BASE (0xdeadbeef)
+#define BCM_6328_USBDMA_BASE (0xdeadbeef)
+#define BCM_6328_OHCI0_BASE (0xdeadbeef)
+#define BCM_6328_OHCI_PRIV_BASE (0xdeadbeef)
+#define BCM_6328_USBH_PRIV_BASE (0xdeadbeef)
+#define BCM_6328_MPI_BASE (0xdeadbeef)
+#define BCM_6328_PCMCIA_BASE (0xdeadbeef)
+#define BCM_6328_PCIE_BASE (0xb0e40000)
+#define BCM_6328_SDRAM_REGS_BASE (0xdeadbeef)
+#define BCM_6328_DSL_BASE (0xb0001900)
+#define BCM_6328_UBUS_BASE (0xdeadbeef)
+#define BCM_6328_ENET0_BASE (0xdeadbeef)
+#define BCM_6328_ENET1_BASE (0xdeadbeef)
+#define BCM_6328_ENETDMA_BASE (0xb000d800)
+#define BCM_6328_ENETDMAC_BASE (0xb000da00)
+#define BCM_6328_ENETDMAS_BASE (0xb000dc00)
+#define BCM_6328_ENETSW_BASE (0xb0e00000)
+#define BCM_6328_EHCI0_BASE (0x10002500)
+#define BCM_6328_SDRAM_BASE (0xdeadbeef)
+#define BCM_6328_MEMC_BASE (0xdeadbeef)
+#define BCM_6328_DDR_BASE (0xb0003000)
+#define BCM_6328_M2M_BASE (0xdeadbeef)
+#define BCM_6328_ATM_BASE (0xdeadbeef)
+#define BCM_6328_XTM_BASE (0xdeadbeef)
+#define BCM_6328_XTMDMA_BASE (0xb000b800)
+#define BCM_6328_XTMDMAC_BASE (0xdeadbeef)
+#define BCM_6328_XTMDMAS_BASE (0xdeadbeef)
+#define BCM_6328_PCM_BASE (0xb000a800)
+#define BCM_6328_PCMDMA_BASE (0xdeadbeef)
+#define BCM_6328_PCMDMAC_BASE (0xdeadbeef)
+#define BCM_6328_PCMDMAS_BASE (0xdeadbeef)
+#define BCM_6328_RNG_BASE (0xdeadbeef)
+#define BCM_6328_MISC_BASE (0xb0001800)
+/*
* 6338 register sets base address
*/
#define BCM_6338_DSL_LMEM_BASE (0xfff00000)
@@ -162,7 +227,6 @@ enum bcm63xx_regs_set {
#define BCM_6338_UART1_BASE (0xdeadbeef)
#define BCM_6338_GPIO_BASE (0xfffe0400)
#define BCM_6338_SPI_BASE (0xfffe0c00)
-#define BCM_6338_SPI2_BASE (0xdeadbeef)
#define BCM_6338_UDC0_BASE (0xdeadbeef)
#define BCM_6338_USBDMA_BASE (0xfffe2400)
#define BCM_6338_OHCI0_BASE (0xdeadbeef)
@@ -170,6 +234,7 @@ enum bcm63xx_regs_set {
#define BCM_6338_USBH_PRIV_BASE (0xdeadbeef)
#define BCM_6338_MPI_BASE (0xfffe3160)
#define BCM_6338_PCMCIA_BASE (0xdeadbeef)
+#define BCM_6338_PCIE_BASE (0xdeadbeef)
#define BCM_6338_SDRAM_REGS_BASE (0xfffe3100)
#define BCM_6338_DSL_BASE (0xfffe1000)
#define BCM_6338_UBUS_BASE (0xdeadbeef)
@@ -193,6 +258,8 @@ enum bcm63xx_regs_set {
#define BCM_6338_PCMDMA_BASE (0xdeadbeef)
#define BCM_6338_PCMDMAC_BASE (0xdeadbeef)
#define BCM_6338_PCMDMAS_BASE (0xdeadbeef)
+#define BCM_6338_RNG_BASE (0xdeadbeef)
+#define BCM_6338_MISC_BASE (0xdeadbeef)
/*
* 6345 register sets base address
@@ -206,7 +273,6 @@ enum bcm63xx_regs_set {
#define BCM_6345_UART1_BASE (0xdeadbeef)
#define BCM_6345_GPIO_BASE (0xfffe0400)
#define BCM_6345_SPI_BASE (0xdeadbeef)
-#define BCM_6345_SPI2_BASE (0xdeadbeef)
#define BCM_6345_UDC0_BASE (0xdeadbeef)
#define BCM_6345_USBDMA_BASE (0xfffe2800)
#define BCM_6345_ENET0_BASE (0xfffe1800)
@@ -216,6 +282,7 @@ enum bcm63xx_regs_set {
#define BCM_6345_ENETSW_BASE (0xdeadbeef)
#define BCM_6345_PCMCIA_BASE (0xfffe2028)
#define BCM_6345_MPI_BASE (0xfffe2000)
+#define BCM_6345_PCIE_BASE (0xdeadbeef)
#define BCM_6345_OHCI0_BASE (0xfffe2100)
#define BCM_6345_OHCI_PRIV_BASE (0xfffe2200)
#define BCM_6345_USBH_PRIV_BASE (0xdeadbeef)
@@ -237,6 +304,8 @@ enum bcm63xx_regs_set {
#define BCM_6345_PCMDMA_BASE (0xdeadbeef)
#define BCM_6345_PCMDMAC_BASE (0xdeadbeef)
#define BCM_6345_PCMDMAS_BASE (0xdeadbeef)
+#define BCM_6345_RNG_BASE (0xdeadbeef)
+#define BCM_6345_MISC_BASE (0xdeadbeef)
/*
* 6348 register sets base address
@@ -249,13 +318,13 @@ enum bcm63xx_regs_set {
#define BCM_6348_UART1_BASE (0xdeadbeef)
#define BCM_6348_GPIO_BASE (0xfffe0400)
#define BCM_6348_SPI_BASE (0xfffe0c00)
-#define BCM_6348_SPI2_BASE (0xdeadbeef)
#define BCM_6348_UDC0_BASE (0xfffe1000)
#define BCM_6348_OHCI0_BASE (0xfffe1b00)
#define BCM_6348_OHCI_PRIV_BASE (0xfffe1c00)
#define BCM_6348_USBH_PRIV_BASE (0xdeadbeef)
#define BCM_6348_MPI_BASE (0xfffe2000)
#define BCM_6348_PCMCIA_BASE (0xfffe2054)
+#define BCM_6348_PCIE_BASE (0xdeadbeef)
#define BCM_6348_SDRAM_REGS_BASE (0xfffe2300)
#define BCM_6348_M2M_BASE (0xfffe2800)
#define BCM_6348_DSL_BASE (0xfffe3000)
@@ -278,6 +347,8 @@ enum bcm63xx_regs_set {
#define BCM_6348_PCMDMA_BASE (0xdeadbeef)
#define BCM_6348_PCMDMAC_BASE (0xdeadbeef)
#define BCM_6348_PCMDMAS_BASE (0xdeadbeef)
+#define BCM_6348_RNG_BASE (0xdeadbeef)
+#define BCM_6348_MISC_BASE (0xdeadbeef)
/*
* 6358 register sets base address
@@ -289,14 +360,14 @@ enum bcm63xx_regs_set {
#define BCM_6358_UART0_BASE (0xfffe0100)
#define BCM_6358_UART1_BASE (0xfffe0120)
#define BCM_6358_GPIO_BASE (0xfffe0080)
-#define BCM_6358_SPI_BASE (0xdeadbeef)
-#define BCM_6358_SPI2_BASE (0xfffe0800)
+#define BCM_6358_SPI_BASE (0xfffe0800)
#define BCM_6358_UDC0_BASE (0xfffe0800)
#define BCM_6358_OHCI0_BASE (0xfffe1400)
#define BCM_6358_OHCI_PRIV_BASE (0xdeadbeef)
#define BCM_6358_USBH_PRIV_BASE (0xfffe1500)
#define BCM_6358_MPI_BASE (0xfffe1000)
#define BCM_6358_PCMCIA_BASE (0xfffe1054)
+#define BCM_6358_PCIE_BASE (0xdeadbeef)
#define BCM_6358_SDRAM_REGS_BASE (0xfffe2300)
#define BCM_6358_M2M_BASE (0xdeadbeef)
#define BCM_6358_DSL_BASE (0xfffe3000)
@@ -319,6 +390,8 @@ enum bcm63xx_regs_set {
#define BCM_6358_PCMDMA_BASE (0xfffe1800)
#define BCM_6358_PCMDMAC_BASE (0xfffe1900)
#define BCM_6358_PCMDMAS_BASE (0xfffe1a00)
+#define BCM_6358_RNG_BASE (0xdeadbeef)
+#define BCM_6358_MISC_BASE (0xdeadbeef)
/*
@@ -331,14 +404,14 @@ enum bcm63xx_regs_set {
#define BCM_6368_UART0_BASE (0xb0000100)
#define BCM_6368_UART1_BASE (0xb0000120)
#define BCM_6368_GPIO_BASE (0xb0000080)
-#define BCM_6368_SPI_BASE (0xdeadbeef)
-#define BCM_6368_SPI2_BASE (0xb0000800)
+#define BCM_6368_SPI_BASE (0xb0000800)
#define BCM_6368_UDC0_BASE (0xdeadbeef)
#define BCM_6368_OHCI0_BASE (0xb0001600)
#define BCM_6368_OHCI_PRIV_BASE (0xdeadbeef)
#define BCM_6368_USBH_PRIV_BASE (0xb0001700)
#define BCM_6368_MPI_BASE (0xb0001000)
#define BCM_6368_PCMCIA_BASE (0xb0001054)
+#define BCM_6368_PCIE_BASE (0xdeadbeef)
#define BCM_6368_SDRAM_REGS_BASE (0xdeadbeef)
#define BCM_6368_M2M_BASE (0xdeadbeef)
#define BCM_6368_DSL_BASE (0xdeadbeef)
@@ -361,6 +434,8 @@ enum bcm63xx_regs_set {
#define BCM_6368_PCMDMA_BASE (0xb0005800)
#define BCM_6368_PCMDMAC_BASE (0xb0005a00)
#define BCM_6368_PCMDMAS_BASE (0xb0005c00)
+#define BCM_6368_RNG_BASE (0xb0004180)
+#define BCM_6368_MISC_BASE (0xdeadbeef)
extern const unsigned long *bcm63xx_regs_base;
@@ -379,13 +454,13 @@ extern const unsigned long *bcm63xx_regs_base;
__GEN_RSET_BASE(__cpu, UART1) \
__GEN_RSET_BASE(__cpu, GPIO) \
__GEN_RSET_BASE(__cpu, SPI) \
- __GEN_RSET_BASE(__cpu, SPI2) \
__GEN_RSET_BASE(__cpu, UDC0) \
__GEN_RSET_BASE(__cpu, OHCI0) \
__GEN_RSET_BASE(__cpu, OHCI_PRIV) \
__GEN_RSET_BASE(__cpu, USBH_PRIV) \
__GEN_RSET_BASE(__cpu, MPI) \
__GEN_RSET_BASE(__cpu, PCMCIA) \
+ __GEN_RSET_BASE(__cpu, PCIE) \
__GEN_RSET_BASE(__cpu, DSL) \
__GEN_RSET_BASE(__cpu, ENET0) \
__GEN_RSET_BASE(__cpu, ENET1) \
@@ -407,6 +482,8 @@ extern const unsigned long *bcm63xx_regs_base;
__GEN_RSET_BASE(__cpu, PCMDMA) \
__GEN_RSET_BASE(__cpu, PCMDMAC) \
__GEN_RSET_BASE(__cpu, PCMDMAS) \
+ __GEN_RSET_BASE(__cpu, RNG) \
+ __GEN_RSET_BASE(__cpu, MISC) \
}
#define __GEN_CPU_REGS_TABLE(__cpu) \
@@ -418,13 +495,13 @@ extern const unsigned long *bcm63xx_regs_base;
[RSET_UART1] = BCM_## __cpu ##_UART1_BASE, \
[RSET_GPIO] = BCM_## __cpu ##_GPIO_BASE, \
[RSET_SPI] = BCM_## __cpu ##_SPI_BASE, \
- [RSET_SPI2] = BCM_## __cpu ##_SPI2_BASE, \
[RSET_UDC0] = BCM_## __cpu ##_UDC0_BASE, \
[RSET_OHCI0] = BCM_## __cpu ##_OHCI0_BASE, \
[RSET_OHCI_PRIV] = BCM_## __cpu ##_OHCI_PRIV_BASE, \
[RSET_USBH_PRIV] = BCM_## __cpu ##_USBH_PRIV_BASE, \
[RSET_MPI] = BCM_## __cpu ##_MPI_BASE, \
[RSET_PCMCIA] = BCM_## __cpu ##_PCMCIA_BASE, \
+ [RSET_PCIE] = BCM_## __cpu ##_PCIE_BASE, \
[RSET_DSL] = BCM_## __cpu ##_DSL_BASE, \
[RSET_ENET0] = BCM_## __cpu ##_ENET0_BASE, \
[RSET_ENET1] = BCM_## __cpu ##_ENET1_BASE, \
@@ -446,6 +523,8 @@ extern const unsigned long *bcm63xx_regs_base;
[RSET_PCMDMA] = BCM_## __cpu ##_PCMDMA_BASE, \
[RSET_PCMDMAC] = BCM_## __cpu ##_PCMDMAC_BASE, \
[RSET_PCMDMAS] = BCM_## __cpu ##_PCMDMAS_BASE, \
+ [RSET_RNG] = BCM_## __cpu ##_RNG_BASE, \
+ [RSET_MISC] = BCM_## __cpu ##_MISC_BASE, \
static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
@@ -453,6 +532,9 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
#ifdef BCMCPU_RUNTIME_DETECT
return bcm63xx_regs_base[set];
#else
+#ifdef CONFIG_BCM63XX_CPU_6328
+ __GEN_RSET(6328)
+#endif
#ifdef CONFIG_BCM63XX_CPU_6338
__GEN_RSET(6338)
#endif
@@ -478,6 +560,7 @@ static inline unsigned long bcm63xx_regset_address(enum bcm63xx_regs_set set)
*/
enum bcm63xx_irq {
IRQ_TIMER = 0,
+ IRQ_SPI,
IRQ_UART0,
IRQ_UART1,
IRQ_DSL,
@@ -506,9 +589,51 @@ enum bcm63xx_irq {
};
/*
+ * 6328 irqs
+ */
+#define BCM_6328_HIGH_IRQ_BASE (IRQ_INTERNAL_BASE + 32)
+
+#define BCM_6328_TIMER_IRQ (IRQ_INTERNAL_BASE + 31)
+#define BCM_6328_SPI_IRQ 0
+#define BCM_6328_UART0_IRQ (IRQ_INTERNAL_BASE + 28)
+#define BCM_6328_UART1_IRQ (BCM_6328_HIGH_IRQ_BASE + 7)
+#define BCM_6328_DSL_IRQ (IRQ_INTERNAL_BASE + 4)
+#define BCM_6328_UDC0_IRQ 0
+#define BCM_6328_ENET0_IRQ 0
+#define BCM_6328_ENET1_IRQ 0
+#define BCM_6328_ENET_PHY_IRQ (IRQ_INTERNAL_BASE + 12)
+#define BCM_6328_OHCI0_IRQ (IRQ_INTERNAL_BASE + 9)
+#define BCM_6328_EHCI0_IRQ (IRQ_INTERNAL_BASE + 10)
+#define BCM_6328_PCMCIA_IRQ 0
+#define BCM_6328_ENET0_RXDMA_IRQ 0
+#define BCM_6328_ENET0_TXDMA_IRQ 0
+#define BCM_6328_ENET1_RXDMA_IRQ 0
+#define BCM_6328_ENET1_TXDMA_IRQ 0
+#define BCM_6328_PCI_IRQ (IRQ_INTERNAL_BASE + 23)
+#define BCM_6328_ATM_IRQ 0
+#define BCM_6328_ENETSW_RXDMA0_IRQ (BCM_6328_HIGH_IRQ_BASE + 0)
+#define BCM_6328_ENETSW_RXDMA1_IRQ (BCM_6328_HIGH_IRQ_BASE + 1)
+#define BCM_6328_ENETSW_RXDMA2_IRQ (BCM_6328_HIGH_IRQ_BASE + 2)
+#define BCM_6328_ENETSW_RXDMA3_IRQ (BCM_6328_HIGH_IRQ_BASE + 3)
+#define BCM_6328_ENETSW_TXDMA0_IRQ (BCM_6328_HIGH_IRQ_BASE + 4)
+#define BCM_6328_ENETSW_TXDMA1_IRQ (BCM_6328_HIGH_IRQ_BASE + 5)
+#define BCM_6328_ENETSW_TXDMA2_IRQ (BCM_6328_HIGH_IRQ_BASE + 6)
+#define BCM_6328_ENETSW_TXDMA3_IRQ (BCM_6328_HIGH_IRQ_BASE + 7)
+#define BCM_6328_XTM_IRQ (BCM_6328_HIGH_IRQ_BASE + 31)
+#define BCM_6328_XTM_DMA0_IRQ (BCM_6328_HIGH_IRQ_BASE + 11)
+
+#define BCM_6328_PCM_DMA0_IRQ (IRQ_INTERNAL_BASE + 2)
+#define BCM_6328_PCM_DMA1_IRQ (IRQ_INTERNAL_BASE + 3)
+#define BCM_6328_EXT_IRQ0 (IRQ_INTERNAL_BASE + 24)
+#define BCM_6328_EXT_IRQ1 (IRQ_INTERNAL_BASE + 25)
+#define BCM_6328_EXT_IRQ2 (IRQ_INTERNAL_BASE + 26)
+#define BCM_6328_EXT_IRQ3 (IRQ_INTERNAL_BASE + 27)
+
+/*
* 6338 irqs
*/
#define BCM_6338_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
+#define BCM_6338_SPI_IRQ (IRQ_INTERNAL_BASE + 1)
#define BCM_6338_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
#define BCM_6338_UART1_IRQ 0
#define BCM_6338_DSL_IRQ (IRQ_INTERNAL_BASE + 5)
@@ -539,6 +664,7 @@ enum bcm63xx_irq {
* 6345 irqs
*/
#define BCM_6345_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
+#define BCM_6345_SPI_IRQ 0
#define BCM_6345_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
#define BCM_6345_UART1_IRQ 0
#define BCM_6345_DSL_IRQ (IRQ_INTERNAL_BASE + 3)
@@ -569,6 +695,7 @@ enum bcm63xx_irq {
* 6348 irqs
*/
#define BCM_6348_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
+#define BCM_6348_SPI_IRQ (IRQ_INTERNAL_BASE + 1)
#define BCM_6348_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
#define BCM_6348_UART1_IRQ 0
#define BCM_6348_DSL_IRQ (IRQ_INTERNAL_BASE + 4)
@@ -599,6 +726,7 @@ enum bcm63xx_irq {
* 6358 irqs
*/
#define BCM_6358_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
+#define BCM_6358_SPI_IRQ (IRQ_INTERNAL_BASE + 1)
#define BCM_6358_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
#define BCM_6358_UART1_IRQ (IRQ_INTERNAL_BASE + 3)
#define BCM_6358_DSL_IRQ (IRQ_INTERNAL_BASE + 29)
@@ -638,6 +766,7 @@ enum bcm63xx_irq {
#define BCM_6368_HIGH_IRQ_BASE (IRQ_INTERNAL_BASE + 32)
#define BCM_6368_TIMER_IRQ (IRQ_INTERNAL_BASE + 0)
+#define BCM_6368_SPI_IRQ (IRQ_INTERNAL_BASE + 1)
#define BCM_6368_UART0_IRQ (IRQ_INTERNAL_BASE + 2)
#define BCM_6368_UART1_IRQ (IRQ_INTERNAL_BASE + 3)
#define BCM_6368_DSL_IRQ (IRQ_INTERNAL_BASE + 4)
@@ -677,6 +806,7 @@ extern const int *bcm63xx_irqs;
#define __GEN_CPU_IRQ_TABLE(__cpu) \
[IRQ_TIMER] = BCM_## __cpu ##_TIMER_IRQ, \
+ [IRQ_SPI] = BCM_## __cpu ##_SPI_IRQ, \
[IRQ_UART0] = BCM_## __cpu ##_UART0_IRQ, \
[IRQ_UART1] = BCM_## __cpu ##_UART1_IRQ, \
[IRQ_DSL] = BCM_## __cpu ##_DSL_IRQ, \
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h
new file mode 100644
index 00000000000..354b8481ec4
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_flash.h
@@ -0,0 +1,12 @@
+#ifndef __BCM63XX_FLASH_H
+#define __BCM63XX_FLASH_H
+
+enum {
+ BCM63XX_FLASH_TYPE_PARALLEL,
+ BCM63XX_FLASH_TYPE_SERIAL,
+ BCM63XX_FLASH_TYPE_NAND,
+};
+
+int __init bcm63xx_flash_register(void);
+
+#endif /* __BCM63XX_FLASH_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h
new file mode 100644
index 00000000000..7d98dbe5d4b
--- /dev/null
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_dev_spi.h
@@ -0,0 +1,89 @@
+#ifndef BCM63XX_DEV_SPI_H
+#define BCM63XX_DEV_SPI_H
+
+#include <linux/types.h>
+#include <bcm63xx_io.h>
+#include <bcm63xx_regs.h>
+
+int __init bcm63xx_spi_register(void);
+
+struct bcm63xx_spi_pdata {
+ unsigned int fifo_size;
+ int bus_num;
+ int num_chipselect;
+ u32 speed_hz;
+};
+
+enum bcm63xx_regs_spi {
+ SPI_CMD,
+ SPI_INT_STATUS,
+ SPI_INT_MASK_ST,
+ SPI_INT_MASK,
+ SPI_ST,
+ SPI_CLK_CFG,
+ SPI_FILL_BYTE,
+ SPI_MSG_TAIL,
+ SPI_RX_TAIL,
+ SPI_MSG_CTL,
+ SPI_MSG_DATA,
+ SPI_RX_DATA,
+};
+
+#define __GEN_SPI_RSET_BASE(__cpu, __rset) \
+ case SPI_## __rset: \
+ return SPI_## __cpu ##_## __rset;
+
+#define __GEN_SPI_RSET(__cpu) \
+ switch (reg) { \
+ __GEN_SPI_RSET_BASE(__cpu, CMD) \
+ __GEN_SPI_RSET_BASE(__cpu, INT_STATUS) \
+ __GEN_SPI_RSET_BASE(__cpu, INT_MASK_ST) \
+ __GEN_SPI_RSET_BASE(__cpu, INT_MASK) \
+ __GEN_SPI_RSET_BASE(__cpu, ST) \
+ __GEN_SPI_RSET_BASE(__cpu, CLK_CFG) \
+ __GEN_SPI_RSET_BASE(__cpu, FILL_BYTE) \
+ __GEN_SPI_RSET_BASE(__cpu, MSG_TAIL) \
+ __GEN_SPI_RSET_BASE(__cpu, RX_TAIL) \
+ __GEN_SPI_RSET_BASE(__cpu, MSG_CTL) \
+ __GEN_SPI_RSET_BASE(__cpu, MSG_DATA) \
+ __GEN_SPI_RSET_BASE(__cpu, RX_DATA) \
+ }
+
+#define __GEN_SPI_REGS_TABLE(__cpu) \
+ [SPI_CMD] = SPI_## __cpu ##_CMD, \
+ [SPI_INT_STATUS] = SPI_## __cpu ##_INT_STATUS, \
+ [SPI_INT_MASK_ST] = SPI_## __cpu ##_INT_MASK_ST, \
+ [SPI_INT_MASK] = SPI_## __cpu ##_INT_MASK, \
+ [SPI_ST] = SPI_## __cpu ##_ST, \
+ [SPI_CLK_CFG] = SPI_## __cpu ##_CLK_CFG, \
+ [SPI_FILL_BYTE] = SPI_## __cpu ##_FILL_BYTE, \
+ [SPI_MSG_TAIL] = SPI_## __cpu ##_MSG_TAIL, \
+ [SPI_RX_TAIL] = SPI_## __cpu ##_RX_TAIL, \
+ [SPI_MSG_CTL] = SPI_## __cpu ##_MSG_CTL, \
+ [SPI_MSG_DATA] = SPI_## __cpu ##_MSG_DATA, \
+ [SPI_RX_DATA] = SPI_## __cpu ##_RX_DATA,
+
+static inline unsigned long bcm63xx_spireg(enum bcm63xx_regs_spi reg)
+{
+#ifdef BCMCPU_RUNTIME_DETECT
+ extern const unsigned long *bcm63xx_regs_spi;
+
+ return bcm63xx_regs_spi[reg];
+#else
+#ifdef CONFIG_BCM63XX_CPU_6338
+ __GEN_SPI_RSET(6338)
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6348
+ __GEN_SPI_RSET(6348)
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6358
+ __GEN_SPI_RSET(6358)
+#endif
+#ifdef CONFIG_BCM63XX_CPU_6368
+ __GEN_SPI_RSET(6368)
+#endif
+#endif
+ return 0;
+}
+
+#endif /* BCM63XX_DEV_SPI_H */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
index 1d7dd96aa46..0a9891f7580 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_gpio.h
@@ -9,6 +9,8 @@ int __init bcm63xx_gpio_init(void);
static inline unsigned long bcm63xx_gpio_count(void)
{
switch (bcm63xx_get_cpu_id()) {
+ case BCM6328_CPU_ID:
+ return 32;
case BCM6358_CPU_ID:
return 40;
case BCM6338_CPU_ID:
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
index 72477a6441d..9203d90e610 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_io.h
@@ -40,6 +40,10 @@
#define BCM_CB_MEM_END_PA (BCM_CB_MEM_BASE_PA + \
BCM_CB_MEM_SIZE - 1)
+#define BCM_PCIE_MEM_BASE_PA 0x10f00000
+#define BCM_PCIE_MEM_SIZE (16 * 1024 * 1024)
+#define BCM_PCIE_MEM_END_PA (BCM_PCIE_MEM_BASE_PA + \
+ BCM_PCIE_MEM_SIZE - 1)
/*
* Internal registers are accessed through KSEG3
@@ -85,11 +89,15 @@
#define bcm_mpi_writel(v, o) bcm_rset_writel(RSET_MPI, (v), (o))
#define bcm_pcmcia_readl(o) bcm_rset_readl(RSET_PCMCIA, (o))
#define bcm_pcmcia_writel(v, o) bcm_rset_writel(RSET_PCMCIA, (v), (o))
+#define bcm_pcie_readl(o) bcm_rset_readl(RSET_PCIE, (o))
+#define bcm_pcie_writel(v, o) bcm_rset_writel(RSET_PCIE, (v), (o))
#define bcm_sdram_readl(o) bcm_rset_readl(RSET_SDRAM, (o))
#define bcm_sdram_writel(v, o) bcm_rset_writel(RSET_SDRAM, (v), (o))
#define bcm_memc_readl(o) bcm_rset_readl(RSET_MEMC, (o))
#define bcm_memc_writel(v, o) bcm_rset_writel(RSET_MEMC, (v), (o))
#define bcm_ddr_readl(o) bcm_rset_readl(RSET_DDR, (o))
#define bcm_ddr_writel(v, o) bcm_rset_writel(RSET_DDR, (v), (o))
+#define bcm_misc_readl(o) bcm_rset_readl(RSET_MISC, (o))
+#define bcm_misc_writel(v, o) bcm_rset_writel(RSET_MISC, (v), (o))
#endif /* ! BCM63XX_IO_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
index fdcd78ca1b0..4ccc2a748af 100644
--- a/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
+++ b/arch/mips/include/asm/mach-bcm63xx/bcm63xx_regs.h
@@ -15,6 +15,30 @@
/* Clock Control register */
#define PERF_CKCTL_REG 0x4
+#define CKCTL_6328_PHYMIPS_EN (1 << 0)
+#define CKCTL_6328_ADSL_QPROC_EN (1 << 1)
+#define CKCTL_6328_ADSL_AFE_EN (1 << 2)
+#define CKCTL_6328_ADSL_EN (1 << 3)
+#define CKCTL_6328_MIPS_EN (1 << 4)
+#define CKCTL_6328_SAR_EN (1 << 5)
+#define CKCTL_6328_PCM_EN (1 << 6)
+#define CKCTL_6328_USBD_EN (1 << 7)
+#define CKCTL_6328_USBH_EN (1 << 8)
+#define CKCTL_6328_HSSPI_EN (1 << 9)
+#define CKCTL_6328_PCIE_EN (1 << 10)
+#define CKCTL_6328_ROBOSW_EN (1 << 11)
+
+#define CKCTL_6328_ALL_SAFE_EN (CKCTL_6328_PHYMIPS_EN | \
+ CKCTL_6328_ADSL_QPROC_EN | \
+ CKCTL_6328_ADSL_AFE_EN | \
+ CKCTL_6328_ADSL_EN | \
+ CKCTL_6328_SAR_EN | \
+ CKCTL_6328_PCM_EN | \
+ CKCTL_6328_USBD_EN | \
+ CKCTL_6328_USBH_EN | \
+ CKCTL_6328_ROBOSW_EN | \
+ CKCTL_6328_PCIE_EN)
+
#define CKCTL_6338_ADSLPHY_EN (1 << 0)
#define CKCTL_6338_MPI_EN (1 << 1)
#define CKCTL_6338_DRAM_EN (1 << 2)
@@ -90,35 +114,36 @@
#define CKCTL_6368_PHYMIPS_EN (1 << 6)
#define CKCTL_6368_SWPKT_USB_EN (1 << 7)
#define CKCTL_6368_SWPKT_SAR_EN (1 << 8)
-#define CKCTL_6368_SPI_CLK_EN (1 << 9)
-#define CKCTL_6368_USBD_CLK_EN (1 << 10)
-#define CKCTL_6368_SAR_CLK_EN (1 << 11)
-#define CKCTL_6368_ROBOSW_CLK_EN (1 << 12)
-#define CKCTL_6368_UTOPIA_CLK_EN (1 << 13)
-#define CKCTL_6368_PCM_CLK_EN (1 << 14)
-#define CKCTL_6368_USBH_CLK_EN (1 << 15)
+#define CKCTL_6368_SPI_EN (1 << 9)
+#define CKCTL_6368_USBD_EN (1 << 10)
+#define CKCTL_6368_SAR_EN (1 << 11)
+#define CKCTL_6368_ROBOSW_EN (1 << 12)
+#define CKCTL_6368_UTOPIA_EN (1 << 13)
+#define CKCTL_6368_PCM_EN (1 << 14)
+#define CKCTL_6368_USBH_EN (1 << 15)
#define CKCTL_6368_DISABLE_GLESS_EN (1 << 16)
-#define CKCTL_6368_NAND_CLK_EN (1 << 17)
-#define CKCTL_6368_IPSEC_CLK_EN (1 << 18)
+#define CKCTL_6368_NAND_EN (1 << 17)
+#define CKCTL_6368_IPSEC_EN (1 << 18)
#define CKCTL_6368_ALL_SAFE_EN (CKCTL_6368_SWPKT_USB_EN | \
CKCTL_6368_SWPKT_SAR_EN | \
- CKCTL_6368_SPI_CLK_EN | \
- CKCTL_6368_USBD_CLK_EN | \
- CKCTL_6368_SAR_CLK_EN | \
- CKCTL_6368_ROBOSW_CLK_EN | \
- CKCTL_6368_UTOPIA_CLK_EN | \
- CKCTL_6368_PCM_CLK_EN | \
- CKCTL_6368_USBH_CLK_EN | \
+ CKCTL_6368_SPI_EN | \
+ CKCTL_6368_USBD_EN | \
+ CKCTL_6368_SAR_EN | \
+ CKCTL_6368_ROBOSW_EN | \
+ CKCTL_6368_UTOPIA_EN | \
+ CKCTL_6368_PCM_EN | \
+ CKCTL_6368_USBH_EN | \
CKCTL_6368_DISABLE_GLESS_EN | \
- CKCTL_6368_NAND_CLK_EN | \
- CKCTL_6368_IPSEC_CLK_EN)
+ CKCTL_6368_NAND_EN | \
+ CKCTL_6368_IPSEC_EN)
/* System PLL Control register */
#define PERF_SYS_PLL_CTL_REG 0x8
#define SYS_PLL_SOFT_RESET 0x1
/* Interrupt Mask register */
+#define PERF_IRQMASK_6328_REG 0x20
#define PERF_IRQMASK_6338_REG 0xc
#define PERF_IRQMASK_6345_REG 0xc
#define PERF_IRQMASK_6348_REG 0xc
@@ -126,6 +151,7 @@
#define PERF_IRQMASK_6368_REG 0x20
/* Interrupt Status register */
+#define PERF_IRQSTAT_6328_REG 0x28
#define PERF_IRQSTAT_6338_REG 0x10
#define PERF_IRQSTAT_6345_REG 0x10
#define PERF_IRQSTAT_6348_REG 0x10
@@ -133,6 +159,7 @@
#define PERF_IRQSTAT_6368_REG 0x28
/* External Interrupt Configuration register */
+#define PERF_EXTIRQ_CFG_REG_6328 0x18
#define PERF_EXTIRQ_CFG_REG_6338 0x14
#define PERF_EXTIRQ_CFG_REG_6348 0x14
#define PERF_EXTIRQ_CFG_REG_6358 0x14
@@ -162,8 +189,21 @@
/* Soft Reset register */
#define PERF_SOFTRESET_REG 0x28
+#define PERF_SOFTRESET_6328_REG 0x10
#define PERF_SOFTRESET_6368_REG 0x10
+#define SOFTRESET_6328_SPI_MASK (1 << 0)
+#define SOFTRESET_6328_EPHY_MASK (1 << 1)
+#define SOFTRESET_6328_SAR_MASK (1 << 2)
+#define SOFTRESET_6328_ENETSW_MASK (1 << 3)
+#define SOFTRESET_6328_USBS_MASK (1 << 4)
+#define SOFTRESET_6328_USBH_MASK (1 << 5)
+#define SOFTRESET_6328_PCM_MASK (1 << 6)
+#define SOFTRESET_6328_PCIE_CORE_MASK (1 << 7)
+#define SOFTRESET_6328_PCIE_MASK (1 << 8)
+#define SOFTRESET_6328_PCIE_EXT_MASK (1 << 9)
+#define SOFTRESET_6328_PCIE_HARD_MASK (1 << 10)
+
#define SOFTRESET_6338_SPI_MASK (1 << 0)
#define SOFTRESET_6338_ENET_MASK (1 << 2)
#define SOFTRESET_6338_USBH_MASK (1 << 3)
@@ -307,6 +347,8 @@
/* Watchdog reset length register */
#define WDT_RSTLEN_REG 0x8
+/* Watchdog soft reset register (BCM6328 only) */
+#define WDT_SOFTRESET_REG 0xc
/*************************************************************************
* _REG relative to RSET_UARTx
@@ -507,6 +549,15 @@
#define GPIO_BASEMODE_6368_MASK 0x7
/* those bits must be kept as read in gpio basemode register*/
+#define GPIO_STRAPBUS_REG 0x40
+#define STRAPBUS_6358_BOOT_SEL_PARALLEL (1 << 1)
+#define STRAPBUS_6358_BOOT_SEL_SERIAL (0 << 1)
+#define STRAPBUS_6368_BOOT_SEL_MASK 0x3
+#define STRAPBUS_6368_BOOT_SEL_NAND 0
+#define STRAPBUS_6368_BOOT_SEL_SERIAL 1
+#define STRAPBUS_6368_BOOT_SEL_PARALLEL 3
+
+
/*************************************************************************
* _REG relative to RSET_ENET
*************************************************************************/
@@ -924,6 +975,8 @@
* _REG relative to RSET_DDR
*************************************************************************/
+#define DDR_CSEND_REG 0x8
+
#define DDR_DMIPSPLLCFG_REG 0x18
#define DMIPSPLLCFG_M1_SHIFT 0
#define DMIPSPLLCFG_M1_MASK (0xff << DMIPSPLLCFG_M1_SHIFT)
@@ -973,4 +1026,201 @@
#define M2M_SRCID_REG(x) ((x) * 0x40 + 0x14)
#define M2M_DSTID_REG(x) ((x) * 0x40 + 0x18)
+/*************************************************************************
+ * _REG relative to RSET_RNG
+ *************************************************************************/
+
+#define RNG_CTRL 0x00
+#define RNG_EN (1 << 0)
+
+#define RNG_STAT 0x04
+#define RNG_AVAIL_MASK (0xff000000)
+
+#define RNG_DATA 0x08
+#define RNG_THRES 0x0c
+#define RNG_MASK 0x10
+
+/*************************************************************************
+ * _REG relative to RSET_SPI
+ *************************************************************************/
+
+/* BCM 6338 SPI core */
+#define SPI_6338_CMD 0x00 /* 16-bits register */
+#define SPI_6338_INT_STATUS 0x02
+#define SPI_6338_INT_MASK_ST 0x03
+#define SPI_6338_INT_MASK 0x04
+#define SPI_6338_ST 0x05
+#define SPI_6338_CLK_CFG 0x06
+#define SPI_6338_FILL_BYTE 0x07
+#define SPI_6338_MSG_TAIL 0x09
+#define SPI_6338_RX_TAIL 0x0b
+#define SPI_6338_MSG_CTL 0x40
+#define SPI_6338_MSG_DATA 0x41
+#define SPI_6338_MSG_DATA_SIZE 0x3f
+#define SPI_6338_RX_DATA 0x80
+#define SPI_6338_RX_DATA_SIZE 0x3f
+
+/* BCM 6348 SPI core */
+#define SPI_6348_CMD 0x00 /* 16-bits register */
+#define SPI_6348_INT_STATUS 0x02
+#define SPI_6348_INT_MASK_ST 0x03
+#define SPI_6348_INT_MASK 0x04
+#define SPI_6348_ST 0x05
+#define SPI_6348_CLK_CFG 0x06
+#define SPI_6348_FILL_BYTE 0x07
+#define SPI_6348_MSG_TAIL 0x09
+#define SPI_6348_RX_TAIL 0x0b
+#define SPI_6348_MSG_CTL 0x40
+#define SPI_6348_MSG_DATA 0x41
+#define SPI_6348_MSG_DATA_SIZE 0x3f
+#define SPI_6348_RX_DATA 0x80
+#define SPI_6348_RX_DATA_SIZE 0x3f
+
+/* BCM 6358 SPI core */
+#define SPI_6358_MSG_CTL 0x00 /* 16-bits register */
+#define SPI_6358_MSG_DATA 0x02
+#define SPI_6358_MSG_DATA_SIZE 0x21e
+#define SPI_6358_RX_DATA 0x400
+#define SPI_6358_RX_DATA_SIZE 0x220
+#define SPI_6358_CMD 0x700 /* 16-bits register */
+#define SPI_6358_INT_STATUS 0x702
+#define SPI_6358_INT_MASK_ST 0x703
+#define SPI_6358_INT_MASK 0x704
+#define SPI_6358_ST 0x705
+#define SPI_6358_CLK_CFG 0x706
+#define SPI_6358_FILL_BYTE 0x707
+#define SPI_6358_MSG_TAIL 0x709
+#define SPI_6358_RX_TAIL 0x70B
+
+/* BCM 6358 SPI core */
+#define SPI_6368_MSG_CTL 0x00 /* 16-bits register */
+#define SPI_6368_MSG_DATA 0x02
+#define SPI_6368_MSG_DATA_SIZE 0x21e
+#define SPI_6368_RX_DATA 0x400
+#define SPI_6368_RX_DATA_SIZE 0x220
+#define SPI_6368_CMD 0x700 /* 16-bits register */
+#define SPI_6368_INT_STATUS 0x702
+#define SPI_6368_INT_MASK_ST 0x703
+#define SPI_6368_INT_MASK 0x704
+#define SPI_6368_ST 0x705
+#define SPI_6368_CLK_CFG 0x706
+#define SPI_6368_FILL_BYTE 0x707
+#define SPI_6368_MSG_TAIL 0x709
+#define SPI_6368_RX_TAIL 0x70B
+
+/* Shared SPI definitions */
+
+/* Message configuration */
+#define SPI_FD_RW 0x00
+#define SPI_HD_W 0x01
+#define SPI_HD_R 0x02
+#define SPI_BYTE_CNT_SHIFT 0
+#define SPI_MSG_TYPE_SHIFT 14
+
+/* Command */
+#define SPI_CMD_NOOP 0x00
+#define SPI_CMD_SOFT_RESET 0x01
+#define SPI_CMD_HARD_RESET 0x02
+#define SPI_CMD_START_IMMEDIATE 0x03
+#define SPI_CMD_COMMAND_SHIFT 0
+#define SPI_CMD_COMMAND_MASK 0x000f
+#define SPI_CMD_DEVICE_ID_SHIFT 4
+#define SPI_CMD_PREPEND_BYTE_CNT_SHIFT 8
+#define SPI_CMD_ONE_BYTE_SHIFT 11
+#define SPI_CMD_ONE_WIRE_SHIFT 12
+#define SPI_DEV_ID_0 0
+#define SPI_DEV_ID_1 1
+#define SPI_DEV_ID_2 2
+#define SPI_DEV_ID_3 3
+
+/* Interrupt mask */
+#define SPI_INTR_CMD_DONE 0x01
+#define SPI_INTR_RX_OVERFLOW 0x02
+#define SPI_INTR_TX_UNDERFLOW 0x04
+#define SPI_INTR_TX_OVERFLOW 0x08
+#define SPI_INTR_RX_UNDERFLOW 0x10
+#define SPI_INTR_CLEAR_ALL 0x1f
+
+/* Status */
+#define SPI_RX_EMPTY 0x02
+#define SPI_CMD_BUSY 0x04
+#define SPI_SERIAL_BUSY 0x08
+
+/* Clock configuration */
+#define SPI_CLK_20MHZ 0x00
+#define SPI_CLK_0_391MHZ 0x01
+#define SPI_CLK_0_781MHZ 0x02 /* default */
+#define SPI_CLK_1_563MHZ 0x03
+#define SPI_CLK_3_125MHZ 0x04
+#define SPI_CLK_6_250MHZ 0x05
+#define SPI_CLK_12_50MHZ 0x06
+#define SPI_CLK_MASK 0x07
+#define SPI_SSOFFTIME_MASK 0x38
+#define SPI_SSOFFTIME_SHIFT 3
+#define SPI_BYTE_SWAP 0x80
+
+/*************************************************************************
+ * _REG relative to RSET_MISC
+ *************************************************************************/
+#define MISC_SERDES_CTRL_REG 0x0
+#define SERDES_PCIE_EN (1 << 0)
+#define SERDES_PCIE_EXD_EN (1 << 15)
+
+#define MISC_STRAPBUS_6328_REG 0x240
+#define STRAPBUS_6328_FCVO_SHIFT 7
+#define STRAPBUS_6328_FCVO_MASK (0x1f << STRAPBUS_6328_FCVO_SHIFT)
+#define STRAPBUS_6328_BOOT_SEL_SERIAL (1 << 28)
+#define STRAPBUS_6328_BOOT_SEL_NAND (0 << 28)
+
+/*************************************************************************
+ * _REG relative to RSET_PCIE
+ *************************************************************************/
+
+#define PCIE_CONFIG2_REG 0x408
+#define CONFIG2_BAR1_SIZE_EN 1
+#define CONFIG2_BAR1_SIZE_MASK 0xf
+
+#define PCIE_IDVAL3_REG 0x43c
+#define IDVAL3_CLASS_CODE_MASK 0xffffff
+#define IDVAL3_SUBCLASS_SHIFT 8
+#define IDVAL3_CLASS_SHIFT 16
+
+#define PCIE_DLSTATUS_REG 0x1048
+#define DLSTATUS_PHYLINKUP (1 << 13)
+
+#define PCIE_BRIDGE_OPT1_REG 0x2820
+#define OPT1_RD_BE_OPT_EN (1 << 7)
+#define OPT1_RD_REPLY_BE_FIX_EN (1 << 9)
+#define OPT1_PCIE_BRIDGE_HOLE_DET_EN (1 << 11)
+#define OPT1_L1_INT_STATUS_MASK_POL (1 << 12)
+
+#define PCIE_BRIDGE_OPT2_REG 0x2824
+#define OPT2_UBUS_UR_DECODE_DIS (1 << 2)
+#define OPT2_TX_CREDIT_CHK_EN (1 << 4)
+#define OPT2_CFG_TYPE1_BD_SEL (1 << 7)
+#define OPT2_CFG_TYPE1_BUS_NO_SHIFT 16
+#define OPT2_CFG_TYPE1_BUS_NO_MASK (0xff << OPT2_CFG_TYPE1_BUS_NO_SHIFT)
+
+#define PCIE_BRIDGE_BAR0_BASEMASK_REG 0x2828
+#define PCIE_BRIDGE_BAR1_BASEMASK_REG 0x2830
+#define BASEMASK_REMAP_EN (1 << 0)
+#define BASEMASK_SWAP_EN (1 << 1)
+#define BASEMASK_MASK_SHIFT 4
+#define BASEMASK_MASK_MASK (0xfff << BASEMASK_MASK_SHIFT)
+#define BASEMASK_BASE_SHIFT 20
+#define BASEMASK_BASE_MASK (0xfff << BASEMASK_BASE_SHIFT)
+
+#define PCIE_BRIDGE_BAR0_REBASE_ADDR_REG 0x282c
+#define PCIE_BRIDGE_BAR1_REBASE_ADDR_REG 0x2834
+#define REBASE_ADDR_BASE_SHIFT 20
+#define REBASE_ADDR_BASE_MASK (0xfff << REBASE_ADDR_BASE_SHIFT)
+
+#define PCIE_BRIDGE_RC_INT_MASK_REG 0x2854
+#define PCIE_RC_INT_A (1 << 0)
+#define PCIE_RC_INT_B (1 << 1)
+#define PCIE_RC_INT_C (1 << 2)
+#define PCIE_RC_INT_D (1 << 3)
+
+#define PCIE_DEVICE_OFFSET 0x8000
+
#endif /* BCM63XX_REGS_H_ */
diff --git a/arch/mips/include/asm/mach-bcm63xx/ioremap.h b/arch/mips/include/asm/mach-bcm63xx/ioremap.h
index ef94ba73646..30931c42379 100644
--- a/arch/mips/include/asm/mach-bcm63xx/ioremap.h
+++ b/arch/mips/include/asm/mach-bcm63xx/ioremap.h
@@ -18,6 +18,7 @@ static inline int is_bcm63xx_internal_registers(phys_t offset)
if (offset >= 0xfff00000)
return 1;
break;
+ case BCM6328_CPU_ID:
case BCM6368_CPU_ID:
if (offset >= 0xb0000000 && offset < 0xb1000000)
return 1;
diff --git a/arch/mips/include/asm/mach-cavium-octeon/irq.h b/arch/mips/include/asm/mach-cavium-octeon/irq.h
index 5b05f186e39..418992042f6 100644
--- a/arch/mips/include/asm/mach-cavium-octeon/irq.h
+++ b/arch/mips/include/asm/mach-cavium-octeon/irq.h
@@ -41,61 +41,26 @@ enum octeon_irq {
OCTEON_IRQ_TWSI,
OCTEON_IRQ_TWSI2,
OCTEON_IRQ_RML,
- OCTEON_IRQ_TRACE0,
- OCTEON_IRQ_GMX_DRP0 = OCTEON_IRQ_TRACE0 + 4,
- OCTEON_IRQ_IPD_DRP = OCTEON_IRQ_GMX_DRP0 + 5,
- OCTEON_IRQ_KEY_ZERO,
OCTEON_IRQ_TIMER0,
OCTEON_IRQ_TIMER1,
OCTEON_IRQ_TIMER2,
OCTEON_IRQ_TIMER3,
OCTEON_IRQ_USB0,
OCTEON_IRQ_USB1,
- OCTEON_IRQ_PCM,
- OCTEON_IRQ_MPI,
- OCTEON_IRQ_POWIQ,
- OCTEON_IRQ_IPDPPTHR,
OCTEON_IRQ_MII0,
OCTEON_IRQ_MII1,
OCTEON_IRQ_BOOTDMA,
-
- OCTEON_IRQ_NAND,
- OCTEON_IRQ_MIO, /* Summary of MIO_BOOT_ERR */
- OCTEON_IRQ_IOB, /* Summary of IOB_INT_SUM */
- OCTEON_IRQ_FPA, /* Summary of FPA_INT_SUM */
- OCTEON_IRQ_POW, /* Summary of POW_ECC_ERR */
- OCTEON_IRQ_L2C, /* Summary of L2C_INT_STAT */
- OCTEON_IRQ_IPD, /* Summary of IPD_INT_SUM */
- OCTEON_IRQ_PIP, /* Summary of PIP_INT_REG */
- OCTEON_IRQ_PKO, /* Summary of PKO_REG_ERROR */
- OCTEON_IRQ_ZIP, /* Summary of ZIP_ERROR */
- OCTEON_IRQ_TIM, /* Summary of TIM_REG_ERROR */
- OCTEON_IRQ_RAD, /* Summary of RAD_REG_ERROR */
- OCTEON_IRQ_KEY, /* Summary of KEY_INT_SUM */
- OCTEON_IRQ_DFA, /* Summary of DFA */
- OCTEON_IRQ_USBCTL, /* Summary of USBN0_INT_SUM */
- OCTEON_IRQ_SLI, /* Summary of SLI_INT_SUM */
- OCTEON_IRQ_DPI, /* Summary of DPI_INT_SUM */
- OCTEON_IRQ_AGX0, /* Summary of GMX0*+PCS0_INT*_REG */
- OCTEON_IRQ_AGL = OCTEON_IRQ_AGX0 + 5,
- OCTEON_IRQ_PTP,
- OCTEON_IRQ_PEM0,
- OCTEON_IRQ_PEM1,
- OCTEON_IRQ_SRIO0,
- OCTEON_IRQ_SRIO1,
- OCTEON_IRQ_LMC0,
- OCTEON_IRQ_DFM = OCTEON_IRQ_LMC0 + 4, /* Summary of DFM */
- OCTEON_IRQ_RST,
+#ifndef CONFIG_PCI_MSI
+ OCTEON_IRQ_LAST = 127
+#endif
};
#ifdef CONFIG_PCI_MSI
-/* 152 - 407 represent the MSI interrupts 0-255 */
-#define OCTEON_IRQ_MSI_BIT0 (OCTEON_IRQ_RST + 1)
+/* 256 - 511 represent the MSI interrupts 0-255 */
+#define OCTEON_IRQ_MSI_BIT0 (256)
#define OCTEON_IRQ_MSI_LAST (OCTEON_IRQ_MSI_BIT0 + 255)
#define OCTEON_IRQ_LAST (OCTEON_IRQ_MSI_LAST + 1)
-#else
-#define OCTEON_IRQ_LAST (OCTEON_IRQ_RST + 1)
#endif
#endif
diff --git a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h
index bb5b9a4e29c..986982db7c3 100644
--- a/arch/mips/include/asm/mach-jz4740/jz4740_nand.h
+++ b/arch/mips/include/asm/mach-jz4740/jz4740_nand.h
@@ -19,6 +19,8 @@
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
+#define JZ_NAND_NUM_BANKS 4
+
struct jz_nand_platform_data {
int num_partitions;
struct mtd_partition *partitions;
@@ -27,6 +29,8 @@ struct jz_nand_platform_data {
unsigned int busy_gpio;
+ unsigned char banks[JZ_NAND_NUM_BANKS];
+
void (*ident_callback)(struct platform_device *, struct nand_chip *,
struct mtd_partition **, int *num_partitions);
};
diff --git a/arch/mips/include/asm/mach-loongson/loongson.h b/arch/mips/include/asm/mach-loongson/loongson.h
index 1e29b9dd1d7..5222a007bc2 100644
--- a/arch/mips/include/asm/mach-loongson/loongson.h
+++ b/arch/mips/include/asm/mach-loongson/loongson.h
@@ -14,6 +14,7 @@
#include <linux/io.h>
#include <linux/init.h>
#include <linux/irq.h>
+#include <linux/kconfig.h>
/* loongson internal northbridge initialization */
extern void bonito_irq_init(void);
@@ -66,7 +67,7 @@ extern int mach_i8259_irq(void);
#include <linux/interrupt.h>
static inline void do_perfcnt_IRQ(void)
{
-#if defined(CONFIG_OPROFILE) || defined(CONFIG_OPROFILE_MODULE)
+#if IS_ENABLED(CONFIG_OPROFILE)
do_IRQ(LOONGSON2_PERFCNT_IRQ);
#endif
}
@@ -244,7 +245,6 @@ static inline void do_perfcnt_IRQ(void)
#ifdef CONFIG_CPU_SUPPORTS_CPUFREQ
#include <linux/cpufreq.h>
-extern void loongson2_cpu_wait(void);
extern struct cpufreq_frequency_table loongson2_clockmod_table[];
/* Chip Config */
diff --git a/arch/mips/include/asm/mach-loongson1/irq.h b/arch/mips/include/asm/mach-loongson1/irq.h
new file mode 100644
index 00000000000..da96ed42f73
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson1/irq.h
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
+ *
+ * IRQ mappings for Loongson 1
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+
+#ifndef __ASM_MACH_LOONGSON1_IRQ_H
+#define __ASM_MACH_LOONGSON1_IRQ_H
+
+/*
+ * CPU core Interrupt Numbers
+ */
+#define MIPS_CPU_IRQ_BASE 0
+#define MIPS_CPU_IRQ(x) (MIPS_CPU_IRQ_BASE + (x))
+
+#define SOFTINT0_IRQ MIPS_CPU_IRQ(0)
+#define SOFTINT1_IRQ MIPS_CPU_IRQ(1)
+#define INT0_IRQ MIPS_CPU_IRQ(2)
+#define INT1_IRQ MIPS_CPU_IRQ(3)
+#define INT2_IRQ MIPS_CPU_IRQ(4)
+#define INT3_IRQ MIPS_CPU_IRQ(5)
+#define INT4_IRQ MIPS_CPU_IRQ(6)
+#define TIMER_IRQ MIPS_CPU_IRQ(7) /* cpu timer */
+
+#define MIPS_CPU_IRQS (MIPS_CPU_IRQ(7) + 1 - MIPS_CPU_IRQ_BASE)
+
+/*
+ * INT0~3 Interrupt Numbers
+ */
+#define LS1X_IRQ_BASE MIPS_CPU_IRQS
+#define LS1X_IRQ(n, x) (LS1X_IRQ_BASE + (n << 5) + (x))
+
+#define LS1X_UART0_IRQ LS1X_IRQ(0, 2)
+#define LS1X_UART1_IRQ LS1X_IRQ(0, 3)
+#define LS1X_UART2_IRQ LS1X_IRQ(0, 4)
+#define LS1X_UART3_IRQ LS1X_IRQ(0, 5)
+#define LS1X_CAN0_IRQ LS1X_IRQ(0, 6)
+#define LS1X_CAN1_IRQ LS1X_IRQ(0, 7)
+#define LS1X_SPI0_IRQ LS1X_IRQ(0, 8)
+#define LS1X_SPI1_IRQ LS1X_IRQ(0, 9)
+#define LS1X_AC97_IRQ LS1X_IRQ(0, 10)
+#define LS1X_DMA0_IRQ LS1X_IRQ(0, 13)
+#define LS1X_DMA1_IRQ LS1X_IRQ(0, 14)
+#define LS1X_DMA2_IRQ LS1X_IRQ(0, 15)
+#define LS1X_PWM0_IRQ LS1X_IRQ(0, 17)
+#define LS1X_PWM1_IRQ LS1X_IRQ(0, 18)
+#define LS1X_PWM2_IRQ LS1X_IRQ(0, 19)
+#define LS1X_PWM3_IRQ LS1X_IRQ(0, 20)
+#define LS1X_RTC_INT0_IRQ LS1X_IRQ(0, 21)
+#define LS1X_RTC_INT1_IRQ LS1X_IRQ(0, 22)
+#define LS1X_RTC_INT2_IRQ LS1X_IRQ(0, 23)
+#define LS1X_TOY_INT0_IRQ LS1X_IRQ(0, 24)
+#define LS1X_TOY_INT1_IRQ LS1X_IRQ(0, 25)
+#define LS1X_TOY_INT2_IRQ LS1X_IRQ(0, 26)
+#define LS1X_RTC_TICK_IRQ LS1X_IRQ(0, 27)
+#define LS1X_TOY_TICK_IRQ LS1X_IRQ(0, 28)
+
+#define LS1X_EHCI_IRQ LS1X_IRQ(1, 0)
+#define LS1X_OHCI_IRQ LS1X_IRQ(1, 1)
+#define LS1X_GMAC0_IRQ LS1X_IRQ(1, 2)
+#define LS1X_GMAC1_IRQ LS1X_IRQ(1, 3)
+
+#define LS1X_IRQS (LS1X_IRQ(4, 31) + 1 - LS1X_IRQ_BASE)
+
+#define NR_IRQS (MIPS_CPU_IRQS + LS1X_IRQS)
+
+#endif /* __ASM_MACH_LOONGSON1_IRQ_H */
diff --git a/arch/mips/include/asm/mach-loongson1/loongson1.h b/arch/mips/include/asm/mach-loongson1/loongson1.h
new file mode 100644
index 00000000000..4e18e88cebb
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson1/loongson1.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
+ *
+ * Register mappings for Loongson 1
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+
+#ifndef __ASM_MACH_LOONGSON1_LOONGSON1_H
+#define __ASM_MACH_LOONGSON1_LOONGSON1_H
+
+#define DEFAULT_MEMSIZE 256 /* If no memsize provided */
+
+/* Loongson 1 Register Bases */
+#define LS1X_INTC_BASE 0x1fd01040
+#define LS1X_EHCI_BASE 0x1fe00000
+#define LS1X_OHCI_BASE 0x1fe08000
+#define LS1X_GMAC0_BASE 0x1fe10000
+#define LS1X_GMAC1_BASE 0x1fe20000
+
+#define LS1X_UART0_BASE 0x1fe40000
+#define LS1X_UART1_BASE 0x1fe44000
+#define LS1X_UART2_BASE 0x1fe48000
+#define LS1X_UART3_BASE 0x1fe4c000
+#define LS1X_CAN0_BASE 0x1fe50000
+#define LS1X_CAN1_BASE 0x1fe54000
+#define LS1X_I2C0_BASE 0x1fe58000
+#define LS1X_I2C1_BASE 0x1fe68000
+#define LS1X_I2C2_BASE 0x1fe70000
+#define LS1X_PWM_BASE 0x1fe5c000
+#define LS1X_WDT_BASE 0x1fe5c060
+#define LS1X_RTC_BASE 0x1fe64000
+#define LS1X_AC97_BASE 0x1fe74000
+#define LS1X_NAND_BASE 0x1fe78000
+#define LS1X_CLK_BASE 0x1fe78030
+
+#include <regs-clk.h>
+#include <regs-wdt.h>
+
+#endif /* __ASM_MACH_LOONGSON1_LOONGSON1_H */
diff --git a/arch/mips/include/asm/mach-loongson1/platform.h b/arch/mips/include/asm/mach-loongson1/platform.h
new file mode 100644
index 00000000000..2f171617bad
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson1/platform.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+
+#ifndef __ASM_MACH_LOONGSON1_PLATFORM_H
+#define __ASM_MACH_LOONGSON1_PLATFORM_H
+
+#include <linux/platform_device.h>
+
+extern struct platform_device ls1x_uart_device;
+extern struct platform_device ls1x_eth0_device;
+extern struct platform_device ls1x_ehci_device;
+extern struct platform_device ls1x_rtc_device;
+
+void ls1x_serial_setup(void);
+
+#endif /* __ASM_MACH_LOONGSON1_PLATFORM_H */
diff --git a/arch/mips/include/asm/mach-loongson1/prom.h b/arch/mips/include/asm/mach-loongson1/prom.h
new file mode 100644
index 00000000000..b871dc41b8d
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson1/prom.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __ASM_MACH_LOONGSON1_PROM_H
+#define __ASM_MACH_LOONGSON1_PROM_H
+
+#include <linux/io.h>
+#include <linux/init.h>
+#include <linux/irq.h>
+
+/* environment arguments from bootloader */
+extern unsigned long memsize, highmemsize;
+
+/* loongson-specific command line, env and memory initialization */
+extern char *prom_getenv(char *name);
+extern void __init prom_init_cmdline(void);
+
+#endif /* __ASM_MACH_LOONGSON1_PROM_H */
diff --git a/arch/mips/include/asm/mach-loongson1/regs-clk.h b/arch/mips/include/asm/mach-loongson1/regs-clk.h
new file mode 100644
index 00000000000..8efa7fb9f73
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson1/regs-clk.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
+ *
+ * Loongson 1 Clock Register Definitions.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __ASM_MACH_LOONGSON1_REGS_CLK_H
+#define __ASM_MACH_LOONGSON1_REGS_CLK_H
+
+#define LS1X_CLK_REG(x) \
+ ((void __iomem *)KSEG1ADDR(LS1X_CLK_BASE + (x)))
+
+#define LS1X_CLK_PLL_FREQ LS1X_CLK_REG(0x0)
+#define LS1X_CLK_PLL_DIV LS1X_CLK_REG(0x4)
+
+/* Clock PLL Divisor Register Bits */
+#define DIV_DC_EN (0x1 << 31)
+#define DIV_DC (0x1f << 26)
+#define DIV_CPU_EN (0x1 << 25)
+#define DIV_CPU (0x1f << 20)
+#define DIV_DDR_EN (0x1 << 19)
+#define DIV_DDR (0x1f << 14)
+
+#define DIV_DC_SHIFT 26
+#define DIV_CPU_SHIFT 20
+#define DIV_DDR_SHIFT 14
+
+#endif /* __ASM_MACH_LOONGSON1_REGS_CLK_H */
diff --git a/arch/mips/include/asm/mach-loongson1/regs-wdt.h b/arch/mips/include/asm/mach-loongson1/regs-wdt.h
new file mode 100644
index 00000000000..f897de68c52
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson1/regs-wdt.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
+ *
+ * Loongson 1 watchdog register definitions.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#ifndef __ASM_MACH_LOONGSON1_REGS_WDT_H
+#define __ASM_MACH_LOONGSON1_REGS_WDT_H
+
+#define LS1X_WDT_REG(x) \
+ ((void __iomem *)KSEG1ADDR(LS1X_WDT_BASE + (x)))
+
+#define LS1X_WDT_EN LS1X_WDT_REG(0x0)
+#define LS1X_WDT_SET LS1X_WDT_REG(0x4)
+#define LS1X_WDT_TIMER LS1X_WDT_REG(0x8)
+
+#endif /* __ASM_MACH_LOONGSON1_REGS_WDT_H */
diff --git a/arch/mips/include/asm/mach-loongson1/war.h b/arch/mips/include/asm/mach-loongson1/war.h
new file mode 100644
index 00000000000..e3680a8fb34
--- /dev/null
+++ b/arch/mips/include/asm/mach-loongson1/war.h
@@ -0,0 +1,25 @@
+/*
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ *
+ * Copyright (C) 2002, 2004, 2007 by Ralf Baechle <ralf@linux-mips.org>
+ */
+#ifndef __ASM_MACH_LOONGSON1_WAR_H
+#define __ASM_MACH_LOONGSON1_WAR_H
+
+#define R4600_V1_INDEX_ICACHEOP_WAR 0
+#define R4600_V1_HIT_CACHEOP_WAR 0
+#define R4600_V2_HIT_CACHEOP_WAR 0
+#define R5432_CP0_INTERRUPT_WAR 0
+#define BCM1250_M3_WAR 0
+#define SIBYTE_1956_WAR 0
+#define MIPS4K_ICACHE_REFILL_WAR 0
+#define MIPS_CACHE_SYNC_WAR 0
+#define TX49XX_ICACHE_INDEX_INV_WAR 0
+#define RM9000_CDEX_SMP_WAR 0
+#define ICACHE_REFILLS_WORKAROUND_WAR 0
+#define R10000_LLSC_WAR 0
+#define MIPS34K_MISSED_ITLB_WAR 0
+
+#endif /* __ASM_MACH_LOONGSON1_WAR_H */
diff --git a/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h b/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h
index d193fb68cf2..966db4be377 100644
--- a/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h
+++ b/arch/mips/include/asm/mach-netlogic/cpu-feature-overrides.h
@@ -48,7 +48,6 @@
#define cpu_has_userlocal 1
#define cpu_has_mips32r2 1
#define cpu_has_mips64r2 1
-#define cpu_has_dc_aliases 1
#else
#error "Unknown Netlogic CPU"
#endif
diff --git a/arch/mips/include/asm/mach-tx49xx/mangle-port.h b/arch/mips/include/asm/mach-tx49xx/mangle-port.h
index 5e6912fdd0e..490867b03c8 100644
--- a/arch/mips/include/asm/mach-tx49xx/mangle-port.h
+++ b/arch/mips/include/asm/mach-tx49xx/mangle-port.h
@@ -9,7 +9,7 @@
#define ioswabb(a, x) (x)
#define __mem_ioswabb(a, x) (x)
#if defined(CONFIG_TOSHIBA_RBTX4939) && \
- (defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE)) && \
+ IS_ENABLED(CONFIG_SMC91X) && \
defined(__BIG_ENDIAN)
#define NEEDS_TXX9_IOSWABW
extern u16 (*ioswabw)(volatile u16 *a, u16 x);
diff --git a/arch/mips/include/asm/mipsmtregs.h b/arch/mips/include/asm/mipsmtregs.h
index e71ff4c317f..5b3cb8553e9 100644
--- a/arch/mips/include/asm/mipsmtregs.h
+++ b/arch/mips/include/asm/mipsmtregs.h
@@ -28,6 +28,9 @@
#define read_c0_vpeconf0() __read_32bit_c0_register($1, 2)
#define write_c0_vpeconf0(val) __write_32bit_c0_register($1, 2, val)
+#define read_c0_vpeconf1() __read_32bit_c0_register($1, 3)
+#define write_c0_vpeconf1(val) __write_32bit_c0_register($1, 3, val)
+
#define read_c0_tcstatus() __read_32bit_c0_register($2, 1)
#define write_c0_tcstatus(val) __write_32bit_c0_register($2, 1, val)
@@ -124,6 +127,14 @@
#define VPECONF0_XTC_SHIFT 21
#define VPECONF0_XTC (_ULCAST_(0xff) << VPECONF0_XTC_SHIFT)
+/* VPEConf1 fields (per VPE) */
+#define VPECONF1_NCP1_SHIFT 0
+#define VPECONF1_NCP1 (_ULCAST_(0xff) << VPECONF1_NCP1_SHIFT)
+#define VPECONF1_NCP2_SHIFT 10
+#define VPECONF1_NCP2 (_ULCAST_(0xff) << VPECONF1_NCP2_SHIFT)
+#define VPECONF1_NCX_SHIFT 20
+#define VPECONF1_NCX (_ULCAST_(0xff) << VPECONF1_NCX_SHIFT)
+
/* TCStatus fields (per TC) */
#define TCSTATUS_TASID (_ULCAST_(0xff))
#define TCSTATUS_IXMT_SHIFT 10
@@ -350,6 +361,8 @@ do { \
#define write_vpe_c0_vpecontrol(val) mttc0(1, 1, val)
#define read_vpe_c0_vpeconf0() mftc0(1, 2)
#define write_vpe_c0_vpeconf0(val) mttc0(1, 2, val)
+#define read_vpe_c0_vpeconf1() mftc0(1, 3)
+#define write_vpe_c0_vpeconf1(val) mttc0(1, 3, val)
#define read_vpe_c0_count() mftc0(9, 0)
#define write_vpe_c0_count(val) mttc0(9, 0, val)
#define read_vpe_c0_status() mftc0(12, 0)
diff --git a/arch/mips/include/asm/module.h b/arch/mips/include/asm/module.h
index 530008048c6..7531ecd654d 100644
--- a/arch/mips/include/asm/module.h
+++ b/arch/mips/include/asm/module.h
@@ -117,6 +117,8 @@ search_module_dbetables(unsigned long addr)
#define MODULE_PROC_FAMILY "RM9000 "
#elif defined CONFIG_CPU_SB1
#define MODULE_PROC_FAMILY "SB1 "
+#elif defined CONFIG_CPU_LOONGSON1
+#define MODULE_PROC_FAMILY "LOONGSON1 "
#elif defined CONFIG_CPU_LOONGSON2
#define MODULE_PROC_FAMILY "LOONGSON2 "
#elif defined CONFIG_CPU_CAVIUM_OCTEON
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h b/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h
index bf7d41deb9b..7b63a6b722a 100644
--- a/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h
+++ b/arch/mips/include/asm/netlogic/xlp-hal/cpucontrol.h
@@ -47,7 +47,9 @@
#define CPU_BLOCKID_MAP 10
#define LSU_DEFEATURE 0x304
-#define LSU_CERRLOG_REGID 0x09
+#define LSU_DEBUG_ADDR 0x305
+#define LSU_DEBUG_DATA0 0x306
+#define LSU_CERRLOG_REGID 0x309
#define SCHED_DEFEATURE 0x700
/* Offsets of interest from the 'MAP' Block */
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/iomap.h b/arch/mips/include/asm/netlogic/xlp-hal/iomap.h
index 86cc3391e50..2c63f975464 100644
--- a/arch/mips/include/asm/netlogic/xlp-hal/iomap.h
+++ b/arch/mips/include/asm/netlogic/xlp-hal/iomap.h
@@ -36,6 +36,9 @@
#define __NLM_HAL_IOMAP_H__
#define XLP_DEFAULT_IO_BASE 0x18000000
+#define XLP_DEFAULT_PCI_ECFG_BASE XLP_DEFAULT_IO_BASE
+#define XLP_DEFAULT_PCI_CFG_BASE 0x1c000000
+
#define NMI_BASE 0xbfc00000
#define XLP_IO_CLK 133333333
@@ -129,7 +132,7 @@
#define PCI_DEVICE_ID_NLM_PIC 0x1003
#define PCI_DEVICE_ID_NLM_PCIE 0x1004
#define PCI_DEVICE_ID_NLM_EHCI 0x1007
-#define PCI_DEVICE_ID_NLM_ILK 0x1008
+#define PCI_DEVICE_ID_NLM_OHCI 0x1008
#define PCI_DEVICE_ID_NLM_NAE 0x1009
#define PCI_DEVICE_ID_NLM_POE 0x100A
#define PCI_DEVICE_ID_NLM_FMN 0x100B
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/pcibus.h b/arch/mips/include/asm/netlogic/xlp-hal/pcibus.h
new file mode 100644
index 00000000000..66c323d1bd7
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/xlp-hal/pcibus.h
@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * All Rights Reserved
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the Broadcom
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BROADCOM ``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 BROADCOM OR CONTRIBUTORS 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.
+ */
+
+#ifndef __NLM_HAL_PCIBUS_H__
+#define __NLM_HAL_PCIBUS_H__
+
+/* PCIE Memory and IO regions */
+#define PCIE_MEM_BASE 0xd0000000ULL
+#define PCIE_MEM_LIMIT 0xdfffffffULL
+#define PCIE_IO_BASE 0x14000000ULL
+#define PCIE_IO_LIMIT 0x15ffffffULL
+
+#define PCIE_BRIDGE_CMD 0x1
+#define PCIE_BRIDGE_MSI_CAP 0x14
+#define PCIE_BRIDGE_MSI_ADDRL 0x15
+#define PCIE_BRIDGE_MSI_ADDRH 0x16
+#define PCIE_BRIDGE_MSI_DATA 0x17
+
+/* XLP Global PCIE configuration space registers */
+#define PCIE_BYTE_SWAP_MEM_BASE 0x247
+#define PCIE_BYTE_SWAP_MEM_LIM 0x248
+#define PCIE_BYTE_SWAP_IO_BASE 0x249
+#define PCIE_BYTE_SWAP_IO_LIM 0x24A
+#define PCIE_MSI_STATUS 0x25A
+#define PCIE_MSI_EN 0x25B
+#define PCIE_INT_EN0 0x261
+
+/* PCIE_MSI_EN */
+#define PCIE_MSI_VECTOR_INT_EN 0xFFFFFFFF
+
+/* PCIE_INT_EN0 */
+#define PCIE_MSI_INT_EN (1 << 9)
+
+#ifndef __ASSEMBLY__
+
+#define nlm_read_pcie_reg(b, r) nlm_read_reg(b, r)
+#define nlm_write_pcie_reg(b, r, v) nlm_write_reg(b, r, v)
+#define nlm_get_pcie_base(node, inst) \
+ nlm_pcicfg_base(XLP_IO_PCIE_OFFSET(node, inst))
+#define nlm_get_pcie_regbase(node, inst) \
+ (nlm_get_pcie_base(node, inst) + XLP_IO_PCI_HDRSZ)
+
+int xlp_pcie_link_irt(int link);
+#endif
+#endif /* __NLM_HAL_PCIBUS_H__ */
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/pic.h b/arch/mips/include/asm/netlogic/xlp-hal/pic.h
index b6628f7ccf7..ad8b80233a6 100644
--- a/arch/mips/include/asm/netlogic/xlp-hal/pic.h
+++ b/arch/mips/include/asm/netlogic/xlp-hal/pic.h
@@ -201,7 +201,11 @@
#define PIC_NUM_USB_IRTS 6
#define PIC_IRT_USB_0_INDEX 115
#define PIC_IRT_EHCI_0_INDEX 115
+#define PIC_IRT_OHCI_0_INDEX 116
+#define PIC_IRT_OHCI_1_INDEX 117
#define PIC_IRT_EHCI_1_INDEX 118
+#define PIC_IRT_OHCI_2_INDEX 119
+#define PIC_IRT_OHCI_3_INDEX 120
#define PIC_IRT_USB_INDEX(num) ((num) + PIC_IRT_USB_0_INDEX)
/* 115 to 120 */
#define PIC_IRT_GDX_INDEX 121
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/usb.h b/arch/mips/include/asm/netlogic/xlp-hal/usb.h
new file mode 100644
index 00000000000..a9cd350dfb6
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/xlp-hal/usb.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * All Rights Reserved
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the Broadcom
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BROADCOM ``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 BROADCOM OR CONTRIBUTORS 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.
+ */
+
+#ifndef __NLM_HAL_USB_H__
+#define __NLM_HAL_USB_H__
+
+#define USB_CTL_0 0x01
+#define USB_PHY_0 0x0A
+#define USB_PHY_RESET 0x01
+#define USB_PHY_PORT_RESET_0 0x10
+#define USB_PHY_PORT_RESET_1 0x20
+#define USB_CONTROLLER_RESET 0x01
+#define USB_INT_STATUS 0x0E
+#define USB_INT_EN 0x0F
+#define USB_PHY_INTERRUPT_EN 0x01
+#define USB_OHCI_INTERRUPT_EN 0x02
+#define USB_OHCI_INTERRUPT1_EN 0x04
+#define USB_OHCI_INTERRUPT2_EN 0x08
+#define USB_CTRL_INTERRUPT_EN 0x10
+
+#ifndef __ASSEMBLY__
+
+#define nlm_read_usb_reg(b, r) nlm_read_reg(b, r)
+#define nlm_write_usb_reg(b, r, v) nlm_write_reg(b, r, v)
+#define nlm_get_usb_pcibase(node, inst) \
+ nlm_pcicfg_base(XLP_IO_USB_OFFSET(node, inst))
+#define nlm_get_usb_hcd_base(node, inst) \
+ nlm_xkphys_map_pcibar0(nlm_get_usb_pcibase(node, inst))
+#define nlm_get_usb_regbase(node, inst) \
+ (nlm_get_usb_pcibase(node, inst) + XLP_IO_PCI_HDRSZ)
+
+#endif
+#endif /* __NLM_HAL_USB_H__ */
diff --git a/arch/mips/include/asm/netlogic/xlp-hal/xlp.h b/arch/mips/include/asm/netlogic/xlp-hal/xlp.h
index 1540588e396..7e47209327a 100644
--- a/arch/mips/include/asm/netlogic/xlp-hal/xlp.h
+++ b/arch/mips/include/asm/netlogic/xlp-hal/xlp.h
@@ -35,8 +35,21 @@
#ifndef _NLM_HAL_XLP_H
#define _NLM_HAL_XLP_H
-#define PIC_UART_0_IRQ 17
-#define PIC_UART_1_IRQ 18
+#define PIC_UART_0_IRQ 17
+#define PIC_UART_1_IRQ 18
+#define PIC_PCIE_LINK_0_IRQ 19
+#define PIC_PCIE_LINK_1_IRQ 20
+#define PIC_PCIE_LINK_2_IRQ 21
+#define PIC_PCIE_LINK_3_IRQ 22
+#define PIC_EHCI_0_IRQ 23
+#define PIC_EHCI_1_IRQ 24
+#define PIC_OHCI_0_IRQ 25
+#define PIC_OHCI_1_IRQ 26
+#define PIC_OHCI_2_IRQ 27
+#define PIC_OHCI_3_IRQ 28
+#define PIC_MMC_IRQ 29
+#define PIC_I2C_0_IRQ 30
+#define PIC_I2C_1_IRQ 31
#ifndef __ASSEMBLY__
diff --git a/arch/mips/include/asm/netlogic/xlr/bridge.h b/arch/mips/include/asm/netlogic/xlr/bridge.h
new file mode 100644
index 00000000000..2d02428c4f1
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/xlr/bridge.h
@@ -0,0 +1,104 @@
+/*
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * All Rights Reserved
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the Broadcom
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BROADCOM ``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 BROADCOM OR CONTRIBUTORS 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.
+ */
+#ifndef _ASM_NLM_BRIDGE_H_
+#define _ASM_NLM_BRIDGE_H_
+
+#define BRIDGE_DRAM_0_BAR 0
+#define BRIDGE_DRAM_1_BAR 1
+#define BRIDGE_DRAM_2_BAR 2
+#define BRIDGE_DRAM_3_BAR 3
+#define BRIDGE_DRAM_4_BAR 4
+#define BRIDGE_DRAM_5_BAR 5
+#define BRIDGE_DRAM_6_BAR 6
+#define BRIDGE_DRAM_7_BAR 7
+#define BRIDGE_DRAM_CHN_0_MTR_0_BAR 8
+#define BRIDGE_DRAM_CHN_0_MTR_1_BAR 9
+#define BRIDGE_DRAM_CHN_0_MTR_2_BAR 10
+#define BRIDGE_DRAM_CHN_0_MTR_3_BAR 11
+#define BRIDGE_DRAM_CHN_0_MTR_4_BAR 12
+#define BRIDGE_DRAM_CHN_0_MTR_5_BAR 13
+#define BRIDGE_DRAM_CHN_0_MTR_6_BAR 14
+#define BRIDGE_DRAM_CHN_0_MTR_7_BAR 15
+#define BRIDGE_DRAM_CHN_1_MTR_0_BAR 16
+#define BRIDGE_DRAM_CHN_1_MTR_1_BAR 17
+#define BRIDGE_DRAM_CHN_1_MTR_2_BAR 18
+#define BRIDGE_DRAM_CHN_1_MTR_3_BAR 19
+#define BRIDGE_DRAM_CHN_1_MTR_4_BAR 20
+#define BRIDGE_DRAM_CHN_1_MTR_5_BAR 21
+#define BRIDGE_DRAM_CHN_1_MTR_6_BAR 22
+#define BRIDGE_DRAM_CHN_1_MTR_7_BAR 23
+#define BRIDGE_CFG_BAR 24
+#define BRIDGE_PHNX_IO_BAR 25
+#define BRIDGE_FLASH_BAR 26
+#define BRIDGE_SRAM_BAR 27
+#define BRIDGE_HTMEM_BAR 28
+#define BRIDGE_HTINT_BAR 29
+#define BRIDGE_HTPIC_BAR 30
+#define BRIDGE_HTSM_BAR 31
+#define BRIDGE_HTIO_BAR 32
+#define BRIDGE_HTCFG_BAR 33
+#define BRIDGE_PCIXCFG_BAR 34
+#define BRIDGE_PCIXMEM_BAR 35
+#define BRIDGE_PCIXIO_BAR 36
+#define BRIDGE_DEVICE_MASK 37
+#define BRIDGE_AERR_INTR_LOG1 38
+#define BRIDGE_AERR_INTR_LOG2 39
+#define BRIDGE_AERR_INTR_LOG3 40
+#define BRIDGE_AERR_DEV_STAT 41
+#define BRIDGE_AERR1_LOG1 42
+#define BRIDGE_AERR1_LOG2 43
+#define BRIDGE_AERR1_LOG3 44
+#define BRIDGE_AERR1_DEV_STAT 45
+#define BRIDGE_AERR_INTR_EN 46
+#define BRIDGE_AERR_UPG 47
+#define BRIDGE_AERR_CLEAR 48
+#define BRIDGE_AERR1_CLEAR 49
+#define BRIDGE_SBE_COUNTS 50
+#define BRIDGE_DBE_COUNTS 51
+#define BRIDGE_BITERR_INT_EN 52
+
+#define BRIDGE_SYS2IO_CREDITS 53
+#define BRIDGE_EVNT_CNT_CTRL1 54
+#define BRIDGE_EVNT_COUNTER1 55
+#define BRIDGE_EVNT_CNT_CTRL2 56
+#define BRIDGE_EVNT_COUNTER2 57
+#define BRIDGE_RESERVED1 58
+
+#define BRIDGE_DEFEATURE 59
+#define BRIDGE_SCRATCH0 60
+#define BRIDGE_SCRATCH1 61
+#define BRIDGE_SCRATCH2 62
+#define BRIDGE_SCRATCH3 63
+
+#endif
diff --git a/arch/mips/include/asm/netlogic/xlr/flash.h b/arch/mips/include/asm/netlogic/xlr/flash.h
new file mode 100644
index 00000000000..f8aca5472b6
--- /dev/null
+++ b/arch/mips/include/asm/netlogic/xlr/flash.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * All Rights Reserved
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the Broadcom
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BROADCOM ``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 BROADCOM OR CONTRIBUTORS 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.
+ */
+#ifndef _ASM_NLM_FLASH_H_
+#define _ASM_NLM_FLASH_H_
+
+#define FLASH_CSBASE_ADDR(cs) (cs)
+#define FLASH_CSADDR_MASK(cs) (0x10 + (cs))
+#define FLASH_CSDEV_PARM(cs) (0x20 + (cs))
+#define FLASH_CSTIME_PARMA(cs) (0x30 + (cs))
+#define FLASH_CSTIME_PARMB(cs) (0x40 + (cs))
+
+#define FLASH_INT_MASK 0x50
+#define FLASH_INT_STATUS 0x60
+#define FLASH_ERROR_STATUS 0x70
+#define FLASH_ERROR_ADDR 0x80
+
+#define FLASH_NAND_CLE(cs) (0x90 + (cs))
+#define FLASH_NAND_ALE(cs) (0xa0 + (cs))
+
+#define FLASH_NAND_CSDEV_PARAM 0x000041e6
+#define FLASH_NAND_CSTIME_PARAMA 0x4f400e22
+#define FLASH_NAND_CSTIME_PARAMB 0x000083cf
+
+#endif
diff --git a/arch/mips/include/asm/netlogic/xlr/gpio.h b/arch/mips/include/asm/netlogic/xlr/gpio.h
index 51f6ad4aeb1..8492e835b11 100644
--- a/arch/mips/include/asm/netlogic/xlr/gpio.h
+++ b/arch/mips/include/asm/netlogic/xlr/gpio.h
@@ -35,39 +35,40 @@
#ifndef _ASM_NLM_GPIO_H
#define _ASM_NLM_GPIO_H
-#define NETLOGIC_GPIO_INT_EN_REG 0
-#define NETLOGIC_GPIO_INPUT_INVERSION_REG 1
-#define NETLOGIC_GPIO_IO_DIR_REG 2
-#define NETLOGIC_GPIO_IO_DATA_WR_REG 3
-#define NETLOGIC_GPIO_IO_DATA_RD_REG 4
+#define GPIO_INT_EN_REG 0
+#define GPIO_INPUT_INVERSION_REG 1
+#define GPIO_IO_DIR_REG 2
+#define GPIO_IO_DATA_WR_REG 3
+#define GPIO_IO_DATA_RD_REG 4
-#define NETLOGIC_GPIO_SWRESET_REG 8
-#define NETLOGIC_GPIO_DRAM1_CNTRL_REG 9
-#define NETLOGIC_GPIO_DRAM1_RATIO_REG 10
-#define NETLOGIC_GPIO_DRAM1_RESET_REG 11
-#define NETLOGIC_GPIO_DRAM1_STATUS_REG 12
-#define NETLOGIC_GPIO_DRAM2_CNTRL_REG 13
-#define NETLOGIC_GPIO_DRAM2_RATIO_REG 14
-#define NETLOGIC_GPIO_DRAM2_RESET_REG 15
-#define NETLOGIC_GPIO_DRAM2_STATUS_REG 16
+#define GPIO_SWRESET_REG 8
+#define GPIO_DRAM1_CNTRL_REG 9
+#define GPIO_DRAM1_RATIO_REG 10
+#define GPIO_DRAM1_RESET_REG 11
+#define GPIO_DRAM1_STATUS_REG 12
+#define GPIO_DRAM2_CNTRL_REG 13
+#define GPIO_DRAM2_RATIO_REG 14
+#define GPIO_DRAM2_RESET_REG 15
+#define GPIO_DRAM2_STATUS_REG 16
-#define NETLOGIC_GPIO_PWRON_RESET_CFG_REG 21
-#define NETLOGIC_GPIO_BIST_ALL_GO_STATUS_REG 24
-#define NETLOGIC_GPIO_BIST_CPU_GO_STATUS_REG 25
-#define NETLOGIC_GPIO_BIST_DEV_GO_STATUS_REG 26
+#define GPIO_PWRON_RESET_CFG_REG 21
+#define GPIO_BIST_ALL_GO_STATUS_REG 24
+#define GPIO_BIST_CPU_GO_STATUS_REG 25
+#define GPIO_BIST_DEV_GO_STATUS_REG 26
-#define NETLOGIC_GPIO_FUSE_BANK_REG 35
-#define NETLOGIC_GPIO_CPU_RESET_REG 40
-#define NETLOGIC_GPIO_RNG_REG 43
+#define GPIO_FUSE_BANK_REG 35
+#define GPIO_CPU_RESET_REG 40
+#define GPIO_RNG_REG 43
-#define NETLOGIC_PWRON_RESET_PCMCIA_BOOT 17
-#define NETLOGIC_GPIO_LED_BITMAP 0x1700000
-#define NETLOGIC_GPIO_LED_0_SHIFT 20
-#define NETLOGIC_GPIO_LED_1_SHIFT 24
+#define PWRON_RESET_PCMCIA_BOOT 17
-#define NETLOGIC_GPIO_LED_OUTPUT_CODE_RESET 0x01
-#define NETLOGIC_GPIO_LED_OUTPUT_CODE_HARD_RESET 0x02
-#define NETLOGIC_GPIO_LED_OUTPUT_CODE_SOFT_RESET 0x03
-#define NETLOGIC_GPIO_LED_OUTPUT_CODE_MAIN 0x04
+#define GPIO_LED_BITMAP 0x1700000
+#define GPIO_LED_0_SHIFT 20
+#define GPIO_LED_1_SHIFT 24
+
+#define GPIO_LED_OUTPUT_CODE_RESET 0x01
+#define GPIO_LED_OUTPUT_CODE_HARD_RESET 0x02
+#define GPIO_LED_OUTPUT_CODE_SOFT_RESET 0x03
+#define GPIO_LED_OUTPUT_CODE_MAIN 0x04
#endif
diff --git a/arch/mips/include/asm/octeon/cvmx-helper-fpa.h b/arch/mips/include/asm/octeon/cvmx-helper-fpa.h
deleted file mode 100644
index 5ff8c93198d..00000000000
--- a/arch/mips/include/asm/octeon/cvmx-helper-fpa.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/***********************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
- *
- * Helper functions for FPA setup.
- *
- */
-#ifndef __CVMX_HELPER_H_FPA__
-#define __CVMX_HELPER_H_FPA__
-
-/**
- * Allocate memory and initialize the FPA pools using memory
- * from cvmx-bootmem. Sizes of each element in the pools is
- * controlled by the cvmx-config.h header file. Specifying
- * zero for any parameter will cause that FPA pool to not be
- * setup. This is useful if you aren't using some of the
- * hardware and want to save memory.
- *
- * @packet_buffers:
- * Number of packet buffers to allocate
- * @work_queue_entries:
- * Number of work queue entries
- * @pko_buffers:
- * PKO Command buffers. You should at minimum have two per
- * each PKO queue.
- * @tim_buffers:
- * TIM ring buffer command queues. At least two per timer bucket
- * is recommened.
- * @dfa_buffers:
- * DFA command buffer. A relatively small (32 for example)
- * number should work.
- * Returns Zero on success, non-zero if out of memory
- */
-extern int cvmx_helper_initialize_fpa(int packet_buffers,
- int work_queue_entries, int pko_buffers,
- int tim_buffers, int dfa_buffers);
-
-#endif /* __CVMX_HELPER_H__ */
diff --git a/arch/mips/include/asm/octeon/cvmx-helper.h b/arch/mips/include/asm/octeon/cvmx-helper.h
index 3169cd79f2a..0ac6b9f412b 100644
--- a/arch/mips/include/asm/octeon/cvmx-helper.h
+++ b/arch/mips/include/asm/octeon/cvmx-helper.h
@@ -61,8 +61,6 @@ typedef union {
} s;
} cvmx_helper_link_info_t;
-#include "cvmx-helper-fpa.h"
-
#include <asm/octeon/cvmx-helper-errata.h>
#include "cvmx-helper-loop.h"
#include "cvmx-helper-npi.h"
diff --git a/arch/mips/include/asm/octeon/octeon.h b/arch/mips/include/asm/octeon/octeon.h
index f72f768cd3a..1e2486e2357 100644
--- a/arch/mips/include/asm/octeon/octeon.h
+++ b/arch/mips/include/asm/octeon/octeon.h
@@ -215,11 +215,6 @@ struct octeon_cf_data {
int dma_engine; /* -1 for no DMA */
};
-struct octeon_i2c_data {
- unsigned int sys_freq;
- unsigned int i2c_freq;
-};
-
extern void octeon_write_lcd(const char *s);
extern void octeon_check_cpu_bist(void);
extern int octeon_get_boot_debug_flag(void);
diff --git a/arch/mips/include/asm/prom.h b/arch/mips/include/asm/prom.h
index 7206d445bab..8808bf548b9 100644
--- a/arch/mips/include/asm/prom.h
+++ b/arch/mips/include/asm/prom.h
@@ -20,9 +20,6 @@
extern int early_init_dt_scan_memory_arch(unsigned long node,
const char *uname, int depth, void *data);
-extern int reserve_mem_mach(unsigned long addr, unsigned long size);
-extern void free_mem_mach(unsigned long addr, unsigned long size);
-
extern void device_tree_init(void);
static inline unsigned long pci_address_to_pio(phys_addr_t address)
diff --git a/arch/mips/include/asm/smtc.h b/arch/mips/include/asm/smtc.h
index c9736fc0632..8935426a56a 100644
--- a/arch/mips/include/asm/smtc.h
+++ b/arch/mips/include/asm/smtc.h
@@ -33,6 +33,12 @@ typedef long asiduse;
#endif
#endif
+/*
+ * VPE Management information
+ */
+
+#define MAX_SMTC_VPES MAX_SMTC_TLBS /* FIXME: May not always be true. */
+
extern asiduse smtc_live_asid[MAX_SMTC_TLBS][MAX_SMTC_ASIDS];
struct mm_struct;
diff --git a/arch/mips/include/asm/uaccess.h b/arch/mips/include/asm/uaccess.h
index 653a412c036..3b92efef56d 100644
--- a/arch/mips/include/asm/uaccess.h
+++ b/arch/mips/include/asm/uaccess.h
@@ -687,7 +687,7 @@ extern size_t __copy_user(void *__to, const void *__from, size_t __n);
__MODULE_JAL(__copy_user) \
: "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \
: \
- : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \
+ : "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31", \
DADDI_SCRATCH, "memory"); \
__cu_len_r; \
})
@@ -797,7 +797,7 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n);
".set\treorder" \
: "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \
: \
- : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \
+ : "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31", \
DADDI_SCRATCH, "memory"); \
__cu_len_r; \
})
@@ -820,7 +820,7 @@ extern size_t __copy_user_inatomic(void *__to, const void *__from, size_t __n);
".set\treorder" \
: "+r" (__cu_to_r), "+r" (__cu_from_r), "+r" (__cu_len_r) \
: \
- : "$8", "$9", "$10", "$11", "$12", "$15", "$24", "$31", \
+ : "$8", "$9", "$10", "$11", "$12", "$14", "$15", "$24", "$31", \
DADDI_SCRATCH, "memory"); \
__cu_len_r; \
})
diff --git a/arch/mips/include/asm/uasm.h b/arch/mips/include/asm/uasm.h
index 440a21dab57..3d9f75f7ffc 100644
--- a/arch/mips/include/asm/uasm.h
+++ b/arch/mips/include/asm/uasm.h
@@ -6,6 +6,7 @@
* Copyright (C) 2004, 2005, 2006, 2008 Thiemo Seufer
* Copyright (C) 2005 Maciej W. Rozycki
* Copyright (C) 2006 Ralf Baechle (ralf@linux-mips.org)
+ * Copyright (C) 2012 MIPS Technologies, Inc.
*/
#include <linux/types.h>
@@ -62,8 +63,10 @@ void __uasminit uasm_i##op(u32 **buf, unsigned int a, signed int b)
Ip_u2u1s3(_addiu);
Ip_u3u1u2(_addu);
-Ip_u2u1u3(_andi);
Ip_u3u1u2(_and);
+Ip_u2u1u3(_andi);
+Ip_u1u2s3(_bbit0);
+Ip_u1u2s3(_bbit1);
Ip_u1u2s3(_beq);
Ip_u1u2s3(_beql);
Ip_u1s2(_bgez);
@@ -72,55 +75,54 @@ Ip_u1s2(_bltz);
Ip_u1s2(_bltzl);
Ip_u1u2s3(_bne);
Ip_u2s3u1(_cache);
-Ip_u1u2u3(_dmfc0);
-Ip_u1u2u3(_dmtc0);
Ip_u2u1s3(_daddiu);
Ip_u3u1u2(_daddu);
+Ip_u2u1msbu3(_dins);
+Ip_u2u1msbu3(_dinsm);
+Ip_u1u2u3(_dmfc0);
+Ip_u1u2u3(_dmtc0);
+Ip_u2u1u3(_drotr);
+Ip_u2u1u3(_drotr32);
Ip_u2u1u3(_dsll);
Ip_u2u1u3(_dsll32);
Ip_u2u1u3(_dsra);
Ip_u2u1u3(_dsrl);
Ip_u2u1u3(_dsrl32);
-Ip_u2u1u3(_drotr);
-Ip_u2u1u3(_drotr32);
Ip_u3u1u2(_dsubu);
Ip_0(_eret);
Ip_u1(_j);
Ip_u1(_jal);
Ip_u1(_jr);
Ip_u2s3u1(_ld);
+Ip_u3u1u2(_ldx);
Ip_u2s3u1(_ll);
Ip_u2s3u1(_lld);
Ip_u1s2(_lui);
Ip_u2s3u1(_lw);
+Ip_u3u1u2(_lwx);
Ip_u1u2u3(_mfc0);
Ip_u1u2u3(_mtc0);
-Ip_u2u1u3(_ori);
Ip_u3u1u2(_or);
+Ip_u2u1u3(_ori);
Ip_u2s3u1(_pref);
Ip_0(_rfe);
+Ip_u2u1u3(_rotr);
Ip_u2s3u1(_sc);
Ip_u2s3u1(_scd);
Ip_u2s3u1(_sd);
Ip_u2u1u3(_sll);
Ip_u2u1u3(_sra);
Ip_u2u1u3(_srl);
-Ip_u2u1u3(_rotr);
Ip_u3u1u2(_subu);
Ip_u2s3u1(_sw);
+Ip_u1(_syscall);
Ip_0(_tlbp);
Ip_0(_tlbr);
Ip_0(_tlbwi);
Ip_0(_tlbwr);
Ip_u3u1u2(_xor);
Ip_u2u1u3(_xori);
-Ip_u2u1msbu3(_dins);
-Ip_u2u1msbu3(_dinsm);
-Ip_u1(_syscall);
-Ip_u1u2s3(_bbit0);
-Ip_u1u2s3(_bbit1);
-Ip_u3u1u2(_lwx);
-Ip_u3u1u2(_ldx);
+
/* Handle labels. */
struct uasm_label {
@@ -145,37 +147,37 @@ static inline void __uasminit uasm_l##lb(struct uasm_label **lab, u32 *addr) \
/* convenience macros for instructions */
#ifdef CONFIG_64BIT
+# define UASM_i_ADDIU(buf, rs, rt, val) uasm_i_daddiu(buf, rs, rt, val)
+# define UASM_i_ADDU(buf, rs, rt, rd) uasm_i_daddu(buf, rs, rt, rd)
+# define UASM_i_LL(buf, rs, rt, off) uasm_i_lld(buf, rs, rt, off)
# define UASM_i_LW(buf, rs, rt, off) uasm_i_ld(buf, rs, rt, off)
-# define UASM_i_SW(buf, rs, rt, off) uasm_i_sd(buf, rs, rt, off)
+# define UASM_i_LWX(buf, rs, rt, rd) uasm_i_ldx(buf, rs, rt, rd)
+# define UASM_i_MFC0(buf, rt, rd...) uasm_i_dmfc0(buf, rt, rd)
+# define UASM_i_MTC0(buf, rt, rd...) uasm_i_dmtc0(buf, rt, rd)
+# define UASM_i_ROTR(buf, rs, rt, sh) uasm_i_drotr(buf, rs, rt, sh)
+# define UASM_i_SC(buf, rs, rt, off) uasm_i_scd(buf, rs, rt, off)
# define UASM_i_SLL(buf, rs, rt, sh) uasm_i_dsll(buf, rs, rt, sh)
# define UASM_i_SRA(buf, rs, rt, sh) uasm_i_dsra(buf, rs, rt, sh)
# define UASM_i_SRL(buf, rs, rt, sh) uasm_i_dsrl(buf, rs, rt, sh)
# define UASM_i_SRL_SAFE(buf, rs, rt, sh) uasm_i_dsrl_safe(buf, rs, rt, sh)
-# define UASM_i_ROTR(buf, rs, rt, sh) uasm_i_drotr(buf, rs, rt, sh)
-# define UASM_i_MFC0(buf, rt, rd...) uasm_i_dmfc0(buf, rt, rd)
-# define UASM_i_MTC0(buf, rt, rd...) uasm_i_dmtc0(buf, rt, rd)
-# define UASM_i_ADDIU(buf, rs, rt, val) uasm_i_daddiu(buf, rs, rt, val)
-# define UASM_i_ADDU(buf, rs, rt, rd) uasm_i_daddu(buf, rs, rt, rd)
# define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_dsubu(buf, rs, rt, rd)
-# define UASM_i_LL(buf, rs, rt, off) uasm_i_lld(buf, rs, rt, off)
-# define UASM_i_SC(buf, rs, rt, off) uasm_i_scd(buf, rs, rt, off)
-# define UASM_i_LWX(buf, rs, rt, rd) uasm_i_ldx(buf, rs, rt, rd)
+# define UASM_i_SW(buf, rs, rt, off) uasm_i_sd(buf, rs, rt, off)
#else
+# define UASM_i_ADDIU(buf, rs, rt, val) uasm_i_addiu(buf, rs, rt, val)
+# define UASM_i_ADDU(buf, rs, rt, rd) uasm_i_addu(buf, rs, rt, rd)
+# define UASM_i_LL(buf, rs, rt, off) uasm_i_ll(buf, rs, rt, off)
# define UASM_i_LW(buf, rs, rt, off) uasm_i_lw(buf, rs, rt, off)
-# define UASM_i_SW(buf, rs, rt, off) uasm_i_sw(buf, rs, rt, off)
+# define UASM_i_LWX(buf, rs, rt, rd) uasm_i_lwx(buf, rs, rt, rd)
+# define UASM_i_MFC0(buf, rt, rd...) uasm_i_mfc0(buf, rt, rd)
+# define UASM_i_MTC0(buf, rt, rd...) uasm_i_mtc0(buf, rt, rd)
+# define UASM_i_ROTR(buf, rs, rt, sh) uasm_i_rotr(buf, rs, rt, sh)
+# define UASM_i_SC(buf, rs, rt, off) uasm_i_sc(buf, rs, rt, off)
# define UASM_i_SLL(buf, rs, rt, sh) uasm_i_sll(buf, rs, rt, sh)
# define UASM_i_SRA(buf, rs, rt, sh) uasm_i_sra(buf, rs, rt, sh)
# define UASM_i_SRL(buf, rs, rt, sh) uasm_i_srl(buf, rs, rt, sh)
# define UASM_i_SRL_SAFE(buf, rs, rt, sh) uasm_i_srl(buf, rs, rt, sh)
-# define UASM_i_ROTR(buf, rs, rt, sh) uasm_i_rotr(buf, rs, rt, sh)
-# define UASM_i_MFC0(buf, rt, rd...) uasm_i_mfc0(buf, rt, rd)
-# define UASM_i_MTC0(buf, rt, rd...) uasm_i_mtc0(buf, rt, rd)
-# define UASM_i_ADDIU(buf, rs, rt, val) uasm_i_addiu(buf, rs, rt, val)
-# define UASM_i_ADDU(buf, rs, rt, rd) uasm_i_addu(buf, rs, rt, rd)
# define UASM_i_SUBU(buf, rs, rt, rd) uasm_i_subu(buf, rs, rt, rd)
-# define UASM_i_LL(buf, rs, rt, off) uasm_i_ll(buf, rs, rt, off)
-# define UASM_i_SC(buf, rs, rt, off) uasm_i_sc(buf, rs, rt, off)
-# define UASM_i_LWX(buf, rs, rt, rd) uasm_i_lwx(buf, rs, rt, rd)
+# define UASM_i_SW(buf, rs, rt, off) uasm_i_sw(buf, rs, rt, off)
#endif
#define uasm_i_b(buf, off) uasm_i_beq(buf, 0, 0, off)
@@ -183,19 +185,10 @@ static inline void __uasminit uasm_l##lb(struct uasm_label **lab, u32 *addr) \
#define uasm_i_beqzl(buf, rs, off) uasm_i_beql(buf, rs, 0, off)
#define uasm_i_bnez(buf, rs, off) uasm_i_bne(buf, rs, 0, off)
#define uasm_i_bnezl(buf, rs, off) uasm_i_bnel(buf, rs, 0, off)
+#define uasm_i_ehb(buf) uasm_i_sll(buf, 0, 0, 3)
#define uasm_i_move(buf, a, b) UASM_i_ADDU(buf, a, 0, b)
#define uasm_i_nop(buf) uasm_i_sll(buf, 0, 0, 0)
#define uasm_i_ssnop(buf) uasm_i_sll(buf, 0, 0, 1)
-#define uasm_i_ehb(buf) uasm_i_sll(buf, 0, 0, 3)
-
-static inline void uasm_i_dsrl_safe(u32 **p, unsigned int a1,
- unsigned int a2, unsigned int a3)
-{
- if (a3 < 32)
- uasm_i_dsrl(p, a1, a2, a3);
- else
- uasm_i_dsrl32(p, a1, a2, a3 - 32);
-}
static inline void uasm_i_drotr_safe(u32 **p, unsigned int a1,
unsigned int a2, unsigned int a3)
@@ -215,6 +208,15 @@ static inline void uasm_i_dsll_safe(u32 **p, unsigned int a1,
uasm_i_dsll32(p, a1, a2, a3 - 32);
}
+static inline void uasm_i_dsrl_safe(u32 **p, unsigned int a1,
+ unsigned int a2, unsigned int a3)
+{
+ if (a3 < 32)
+ uasm_i_dsrl(p, a1, a2, a3);
+ else
+ uasm_i_dsrl32(p, a1, a2, a3 - 32);
+}
+
/* Handle relocations. */
struct uasm_reloc {
u32 *addr;
@@ -234,16 +236,16 @@ void uasm_copy_handler(struct uasm_reloc *rel, struct uasm_label *lab,
int uasm_insn_has_bdelay(struct uasm_reloc *rel, u32 *addr);
/* Convenience functions for labeled branches. */
-void uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
void uasm_il_b(u32 **p, struct uasm_reloc **r, int lid);
+void uasm_il_bbit0(u32 **p, struct uasm_reloc **r, unsigned int reg,
+ unsigned int bit, int lid);
+void uasm_il_bbit1(u32 **p, struct uasm_reloc **r, unsigned int reg,
+ unsigned int bit, int lid);
void uasm_il_beqz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
void uasm_il_beqzl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
+void uasm_il_bltz(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
void uasm_il_bne(u32 **p, struct uasm_reloc **r, unsigned int reg1,
unsigned int reg2, int lid);
void uasm_il_bnez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
-void uasm_il_bgezl(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
-void uasm_il_bgez(u32 **p, struct uasm_reloc **r, unsigned int reg, int lid);
-void uasm_il_bbit0(u32 **p, struct uasm_reloc **r, unsigned int reg,
- unsigned int bit, int lid);
-void uasm_il_bbit1(u32 **p, struct uasm_reloc **r, unsigned int reg,
- unsigned int bit, int lid);
diff --git a/arch/mips/include/asm/unistd.h b/arch/mips/include/asm/unistd.h
index d8dad5340ea..bebbde01be9 100644
--- a/arch/mips/include/asm/unistd.h
+++ b/arch/mips/include/asm/unistd.h
@@ -1034,7 +1034,6 @@
#ifndef __ASSEMBLY__
#define __ARCH_OMIT_COMPAT_SYS_GETDENTS64
-#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
diff --git a/arch/mips/jz4740/board-qi_lb60.c b/arch/mips/jz4740/board-qi_lb60.c
index 9a91fe9de69..9a3d9de4d04 100644
--- a/arch/mips/jz4740/board-qi_lb60.c
+++ b/arch/mips/jz4740/board-qi_lb60.c
@@ -140,6 +140,7 @@ static void qi_lb60_nand_ident(struct platform_device *pdev,
static struct jz_nand_platform_data qi_lb60_nand_pdata = {
.ident_callback = qi_lb60_nand_ident,
.busy_gpio = 94,
+ .banks = { 1 },
};
/* Keyboard*/
diff --git a/arch/mips/jz4740/platform.c b/arch/mips/jz4740/platform.c
index 10929e2bc6d..e342ed4cbd4 100644
--- a/arch/mips/jz4740/platform.c
+++ b/arch/mips/jz4740/platform.c
@@ -157,11 +157,29 @@ static struct resource jz4740_nand_resources[] = {
.flags = IORESOURCE_MEM,
},
{
- .name = "bank",
+ .name = "bank1",
.start = 0x18000000,
.end = 0x180C0000 - 1,
.flags = IORESOURCE_MEM,
},
+ {
+ .name = "bank2",
+ .start = 0x14000000,
+ .end = 0x140C0000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "bank3",
+ .start = 0x0C000000,
+ .end = 0x0C0C0000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "bank4",
+ .start = 0x08000000,
+ .end = 0x080C0000 - 1,
+ .flags = IORESOURCE_MEM,
+ },
};
struct platform_device jz4740_nand_device = {
diff --git a/arch/mips/jz4740/reset.c b/arch/mips/jz4740/reset.c
index 5f1fb95c0d0..6c0da5afcf1 100644
--- a/arch/mips/jz4740/reset.c
+++ b/arch/mips/jz4740/reset.c
@@ -21,6 +21,9 @@
#include <asm/mach-jz4740/base.h>
#include <asm/mach-jz4740/timer.h>
+#include "reset.h"
+#include "clock.h"
+
static void jz4740_halt(void)
{
while (1) {
@@ -53,21 +56,57 @@ static void jz4740_restart(char *command)
jz4740_halt();
}
-#define JZ_REG_RTC_CTRL 0x00
-#define JZ_REG_RTC_HIBERNATE 0x20
+#define JZ_REG_RTC_CTRL 0x00
+#define JZ_REG_RTC_HIBERNATE 0x20
+#define JZ_REG_RTC_WAKEUP_FILTER 0x24
+#define JZ_REG_RTC_RESET_COUNTER 0x28
-#define JZ_RTC_CTRL_WRDY BIT(7)
+#define JZ_RTC_CTRL_WRDY BIT(7)
+#define JZ_RTC_WAKEUP_FILTER_MASK 0x0000FFE0
+#define JZ_RTC_RESET_COUNTER_MASK 0x00000FE0
-static void jz4740_power_off(void)
+static inline void jz4740_rtc_wait_ready(void __iomem *rtc_base)
{
- void __iomem *rtc_base = ioremap(JZ4740_RTC_BASE_ADDR, 0x24);
uint32_t ctrl;
do {
ctrl = readl(rtc_base + JZ_REG_RTC_CTRL);
} while (!(ctrl & JZ_RTC_CTRL_WRDY));
+}
+static void jz4740_power_off(void)
+{
+ void __iomem *rtc_base = ioremap(JZ4740_RTC_BASE_ADDR, 0x38);
+ unsigned long wakeup_filter_ticks;
+ unsigned long reset_counter_ticks;
+
+ /*
+ * Set minimum wakeup pin assertion time: 100 ms.
+ * Range is 0 to 2 sec if RTC is clocked at 32 kHz.
+ */
+ wakeup_filter_ticks = (100 * jz4740_clock_bdata.rtc_rate) / 1000;
+ if (wakeup_filter_ticks < JZ_RTC_WAKEUP_FILTER_MASK)
+ wakeup_filter_ticks &= JZ_RTC_WAKEUP_FILTER_MASK;
+ else
+ wakeup_filter_ticks = JZ_RTC_WAKEUP_FILTER_MASK;
+ jz4740_rtc_wait_ready(rtc_base);
+ writel(wakeup_filter_ticks, rtc_base + JZ_REG_RTC_WAKEUP_FILTER);
+
+ /*
+ * Set reset pin low-level assertion time after wakeup: 60 ms.
+ * Range is 0 to 125 ms if RTC is clocked at 32 kHz.
+ */
+ reset_counter_ticks = (60 * jz4740_clock_bdata.rtc_rate) / 1000;
+ if (reset_counter_ticks < JZ_RTC_RESET_COUNTER_MASK)
+ reset_counter_ticks &= JZ_RTC_RESET_COUNTER_MASK;
+ else
+ reset_counter_ticks = JZ_RTC_RESET_COUNTER_MASK;
+ jz4740_rtc_wait_ready(rtc_base);
+ writel(reset_counter_ticks, rtc_base + JZ_REG_RTC_RESET_COUNTER);
+
+ jz4740_rtc_wait_ready(rtc_base);
writel(1, rtc_base + JZ_REG_RTC_HIBERNATE);
+
jz4740_halt();
}
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c
index f4630e1082a..1b51046191e 100644
--- a/arch/mips/kernel/cpu-probe.c
+++ b/arch/mips/kernel/cpu-probe.c
@@ -190,6 +190,7 @@ void __init check_wait(void)
case CPU_CAVIUM_OCTEON_PLUS:
case CPU_CAVIUM_OCTEON2:
case CPU_JZRISC:
+ case CPU_LOONGSON1:
case CPU_XLR:
case CPU_XLP:
cpu_wait = r4k_wait;
@@ -330,6 +331,154 @@ static inline void cpu_probe_vmbits(struct cpuinfo_mips *c)
#endif
}
+static char unknown_isa[] __cpuinitdata = KERN_ERR \
+ "Unsupported ISA type, c0.config0: %d.";
+
+static inline unsigned int decode_config0(struct cpuinfo_mips *c)
+{
+ unsigned int config0;
+ int isa;
+
+ config0 = read_c0_config();
+
+ if (((config0 & MIPS_CONF_MT) >> 7) == 1)
+ c->options |= MIPS_CPU_TLB;
+ isa = (config0 & MIPS_CONF_AT) >> 13;
+ switch (isa) {
+ case 0:
+ switch ((config0 & MIPS_CONF_AR) >> 10) {
+ case 0:
+ c->isa_level = MIPS_CPU_ISA_M32R1;
+ break;
+ case 1:
+ c->isa_level = MIPS_CPU_ISA_M32R2;
+ break;
+ default:
+ goto unknown;
+ }
+ break;
+ case 2:
+ switch ((config0 & MIPS_CONF_AR) >> 10) {
+ case 0:
+ c->isa_level = MIPS_CPU_ISA_M64R1;
+ break;
+ case 1:
+ c->isa_level = MIPS_CPU_ISA_M64R2;
+ break;
+ default:
+ goto unknown;
+ }
+ break;
+ default:
+ goto unknown;
+ }
+
+ return config0 & MIPS_CONF_M;
+
+unknown:
+ panic(unknown_isa, config0);
+}
+
+static inline unsigned int decode_config1(struct cpuinfo_mips *c)
+{
+ unsigned int config1;
+
+ config1 = read_c0_config1();
+
+ if (config1 & MIPS_CONF1_MD)
+ c->ases |= MIPS_ASE_MDMX;
+ if (config1 & MIPS_CONF1_WR)
+ c->options |= MIPS_CPU_WATCH;
+ if (config1 & MIPS_CONF1_CA)
+ c->ases |= MIPS_ASE_MIPS16;
+ if (config1 & MIPS_CONF1_EP)
+ c->options |= MIPS_CPU_EJTAG;
+ if (config1 & MIPS_CONF1_FP) {
+ c->options |= MIPS_CPU_FPU;
+ c->options |= MIPS_CPU_32FPR;
+ }
+ if (cpu_has_tlb)
+ c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1;
+
+ return config1 & MIPS_CONF_M;
+}
+
+static inline unsigned int decode_config2(struct cpuinfo_mips *c)
+{
+ unsigned int config2;
+
+ config2 = read_c0_config2();
+
+ if (config2 & MIPS_CONF2_SL)
+ c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
+
+ return config2 & MIPS_CONF_M;
+}
+
+static inline unsigned int decode_config3(struct cpuinfo_mips *c)
+{
+ unsigned int config3;
+
+ config3 = read_c0_config3();
+
+ if (config3 & MIPS_CONF3_SM)
+ c->ases |= MIPS_ASE_SMARTMIPS;
+ if (config3 & MIPS_CONF3_DSP)
+ c->ases |= MIPS_ASE_DSP;
+ if (config3 & MIPS_CONF3_VINT)
+ c->options |= MIPS_CPU_VINT;
+ if (config3 & MIPS_CONF3_VEIC)
+ c->options |= MIPS_CPU_VEIC;
+ if (config3 & MIPS_CONF3_MT)
+ c->ases |= MIPS_ASE_MIPSMT;
+ if (config3 & MIPS_CONF3_ULRI)
+ c->options |= MIPS_CPU_ULRI;
+
+ return config3 & MIPS_CONF_M;
+}
+
+static inline unsigned int decode_config4(struct cpuinfo_mips *c)
+{
+ unsigned int config4;
+
+ config4 = read_c0_config4();
+
+ if ((config4 & MIPS_CONF4_MMUEXTDEF) == MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT
+ && cpu_has_tlb)
+ c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
+
+ c->kscratch_mask = (config4 >> 16) & 0xff;
+
+ return config4 & MIPS_CONF_M;
+}
+
+static void __cpuinit decode_configs(struct cpuinfo_mips *c)
+{
+ int ok;
+
+ /* MIPS32 or MIPS64 compliant CPU. */
+ c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER |
+ MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK;
+
+ c->scache.flags = MIPS_CACHE_NOT_PRESENT;
+
+ ok = decode_config0(c); /* Read Config registers. */
+ BUG_ON(!ok); /* Arch spec violation! */
+ if (ok)
+ ok = decode_config1(c);
+ if (ok)
+ ok = decode_config2(c);
+ if (ok)
+ ok = decode_config3(c);
+ if (ok)
+ ok = decode_config4(c);
+
+ mips_probe_watch_registers(c);
+
+ if (cpu_has_mips_r2)
+ c->core = read_c0_ebase() & 0x3ff;
+}
+
#define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \
| MIPS_CPU_COUNTER)
@@ -638,155 +787,19 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu)
MIPS_CPU_32FPR;
c->tlbsize = 64;
break;
- }
-}
-
-static char unknown_isa[] __cpuinitdata = KERN_ERR \
- "Unsupported ISA type, c0.config0: %d.";
+ case PRID_IMP_LOONGSON1:
+ decode_configs(c);
-static inline unsigned int decode_config0(struct cpuinfo_mips *c)
-{
- unsigned int config0;
- int isa;
+ c->cputype = CPU_LOONGSON1;
- config0 = read_c0_config();
-
- if (((config0 & MIPS_CONF_MT) >> 7) == 1)
- c->options |= MIPS_CPU_TLB;
- isa = (config0 & MIPS_CONF_AT) >> 13;
- switch (isa) {
- case 0:
- switch ((config0 & MIPS_CONF_AR) >> 10) {
- case 0:
- c->isa_level = MIPS_CPU_ISA_M32R1;
- break;
- case 1:
- c->isa_level = MIPS_CPU_ISA_M32R2;
+ switch (c->processor_id & PRID_REV_MASK) {
+ case PRID_REV_LOONGSON1B:
+ __cpu_name[cpu] = "Loongson 1B";
break;
- default:
- goto unknown;
}
- break;
- case 2:
- switch ((config0 & MIPS_CONF_AR) >> 10) {
- case 0:
- c->isa_level = MIPS_CPU_ISA_M64R1;
- break;
- case 1:
- c->isa_level = MIPS_CPU_ISA_M64R2;
- break;
- default:
- goto unknown;
- }
- break;
- default:
- goto unknown;
- }
-
- return config0 & MIPS_CONF_M;
-
-unknown:
- panic(unknown_isa, config0);
-}
-static inline unsigned int decode_config1(struct cpuinfo_mips *c)
-{
- unsigned int config1;
-
- config1 = read_c0_config1();
-
- if (config1 & MIPS_CONF1_MD)
- c->ases |= MIPS_ASE_MDMX;
- if (config1 & MIPS_CONF1_WR)
- c->options |= MIPS_CPU_WATCH;
- if (config1 & MIPS_CONF1_CA)
- c->ases |= MIPS_ASE_MIPS16;
- if (config1 & MIPS_CONF1_EP)
- c->options |= MIPS_CPU_EJTAG;
- if (config1 & MIPS_CONF1_FP) {
- c->options |= MIPS_CPU_FPU;
- c->options |= MIPS_CPU_32FPR;
+ break;
}
- if (cpu_has_tlb)
- c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1;
-
- return config1 & MIPS_CONF_M;
-}
-
-static inline unsigned int decode_config2(struct cpuinfo_mips *c)
-{
- unsigned int config2;
-
- config2 = read_c0_config2();
-
- if (config2 & MIPS_CONF2_SL)
- c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT;
-
- return config2 & MIPS_CONF_M;
-}
-
-static inline unsigned int decode_config3(struct cpuinfo_mips *c)
-{
- unsigned int config3;
-
- config3 = read_c0_config3();
-
- if (config3 & MIPS_CONF3_SM)
- c->ases |= MIPS_ASE_SMARTMIPS;
- if (config3 & MIPS_CONF3_DSP)
- c->ases |= MIPS_ASE_DSP;
- if (config3 & MIPS_CONF3_VINT)
- c->options |= MIPS_CPU_VINT;
- if (config3 & MIPS_CONF3_VEIC)
- c->options |= MIPS_CPU_VEIC;
- if (config3 & MIPS_CONF3_MT)
- c->ases |= MIPS_ASE_MIPSMT;
- if (config3 & MIPS_CONF3_ULRI)
- c->options |= MIPS_CPU_ULRI;
-
- return config3 & MIPS_CONF_M;
-}
-
-static inline unsigned int decode_config4(struct cpuinfo_mips *c)
-{
- unsigned int config4;
-
- config4 = read_c0_config4();
-
- if ((config4 & MIPS_CONF4_MMUEXTDEF) == MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT
- && cpu_has_tlb)
- c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40;
-
- c->kscratch_mask = (config4 >> 16) & 0xff;
-
- return config4 & MIPS_CONF_M;
-}
-
-static void __cpuinit decode_configs(struct cpuinfo_mips *c)
-{
- int ok;
-
- /* MIPS32 or MIPS64 compliant CPU. */
- c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER |
- MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK;
-
- c->scache.flags = MIPS_CACHE_NOT_PRESENT;
-
- ok = decode_config0(c); /* Read Config registers. */
- BUG_ON(!ok); /* Arch spec violation! */
- if (ok)
- ok = decode_config1(c);
- if (ok)
- ok = decode_config2(c);
- if (ok)
- ok = decode_config3(c);
- if (ok)
- ok = decode_config4(c);
-
- mips_probe_watch_registers(c);
-
- if (cpu_has_mips_r2)
- c->core = read_c0_ebase() & 0x3ff;
}
static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu)
diff --git a/arch/mips/kernel/cpufreq/Makefile b/arch/mips/kernel/cpufreq/Makefile
index c3479a432ef..05a5715ee38 100644
--- a/arch/mips/kernel/cpufreq/Makefile
+++ b/arch/mips/kernel/cpufreq/Makefile
@@ -2,4 +2,4 @@
# Makefile for the Linux/MIPS cpufreq.
#
-obj-$(CONFIG_LOONGSON2_CPUFREQ) += loongson2_cpufreq.o loongson2_clock.o
+obj-$(CONFIG_LOONGSON2_CPUFREQ) += loongson2_cpufreq.o
diff --git a/arch/mips/kernel/cpufreq/loongson2_cpufreq.c b/arch/mips/kernel/cpufreq/loongson2_cpufreq.c
index ae5db206347..e7c98e2b78b 100644
--- a/arch/mips/kernel/cpufreq/loongson2_cpufreq.c
+++ b/arch/mips/kernel/cpufreq/loongson2_cpufreq.c
@@ -19,7 +19,7 @@
#include <asm/clock.h>
-#include <loongson.h>
+#include <asm/mach-loongson/loongson.h>
static uint nowait;
@@ -181,6 +181,25 @@ static struct platform_driver platform_driver = {
.id_table = platform_device_ids,
};
+/*
+ * This is the simple version of Loongson-2 wait, Maybe we need do this in
+ * interrupt disabled context.
+ */
+
+static DEFINE_SPINLOCK(loongson2_wait_lock);
+
+static void loongson2_cpu_wait(void)
+{
+ unsigned long flags;
+ u32 cpu_freq;
+
+ spin_lock_irqsave(&loongson2_wait_lock, flags);
+ cpu_freq = LOONGSON_CHIPCFG0;
+ LOONGSON_CHIPCFG0 &= ~0x7; /* Put CPU into wait mode */
+ LOONGSON_CHIPCFG0 = cpu_freq; /* Restore CPU state */
+ spin_unlock_irqrestore(&loongson2_wait_lock, flags);
+}
+
static int __init cpufreq_init(void)
{
int ret;
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c
index eb5e394a465..2f28d3b5568 100644
--- a/arch/mips/kernel/perf_event_mipsxx.c
+++ b/arch/mips/kernel/perf_event_mipsxx.c
@@ -1559,6 +1559,11 @@ init_hw_perf_events(void)
mipspmu.general_event_map = &mipsxxcore_event_map;
mipspmu.cache_event_map = &mipsxxcore_cache_map;
break;
+ case CPU_LOONGSON1:
+ mipspmu.name = "mips/loongson1";
+ mipspmu.general_event_map = &mipsxxcore_event_map;
+ mipspmu.cache_event_map = &mipsxxcore_cache_map;
+ break;
case CPU_CAVIUM_OCTEON:
case CPU_CAVIUM_OCTEON_PLUS:
case CPU_CAVIUM_OCTEON2:
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c
index f11b2bbb826..028f6f837ef 100644
--- a/arch/mips/kernel/prom.c
+++ b/arch/mips/kernel/prom.c
@@ -35,16 +35,6 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size)
return add_memory_region(base, size, BOOT_MEM_RAM);
}
-int __init reserve_mem_mach(unsigned long addr, unsigned long size)
-{
- return reserve_bootmem(addr, size, BOOTMEM_DEFAULT);
-}
-
-void __init free_mem_mach(unsigned long addr, unsigned long size)
-{
- return free_bootmem(addr, size);
-}
-
void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align)
{
return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS));
@@ -77,25 +67,6 @@ void __init early_init_devtree(void *params)
of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL);
}
-void __init device_tree_init(void)
-{
- unsigned long base, size;
-
- if (!initial_boot_params)
- return;
-
- base = virt_to_phys((void *)initial_boot_params);
- size = be32_to_cpu(initial_boot_params->totalsize);
-
- /* Before we do anything, lets reserve the dt blob */
- reserve_mem_mach(base, size);
-
- unflatten_device_tree();
-
- /* free the space reserved for the dt blob */
- free_mem_mach(base, size);
-}
-
void __init __dt_setup_arch(struct boot_param_header *bph)
{
if (be32_to_cpu(bph->magic) != OF_DT_HEADER) {
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 1268392f1d2..31637d8c873 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -102,7 +102,9 @@ asmlinkage __cpuinit void start_secondary(void)
#ifdef CONFIG_MIPS_MT_SMTC
/* Only do cpu_probe for first TC of CPU */
- if ((read_c0_tcbind() & TCBIND_CURTC) == 0)
+ if ((read_c0_tcbind() & TCBIND_CURTC) != 0)
+ __cpu_name[smp_processor_id()] = __cpu_name[0];
+ else
#endif /* CONFIG_MIPS_MT_SMTC */
cpu_probe();
cpu_report();
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c
index 15b5f3cfd20..1d47843d3cc 100644
--- a/arch/mips/kernel/smtc.c
+++ b/arch/mips/kernel/smtc.c
@@ -86,6 +86,13 @@ struct smtc_ipi_q IPIQ[NR_CPUS];
static struct smtc_ipi_q freeIPIq;
+/*
+ * Number of FPU contexts for each VPE
+ */
+
+static int smtc_nconf1[MAX_SMTC_VPES];
+
+
/* Forward declarations */
void ipi_decode(struct smtc_ipi *);
@@ -174,9 +181,9 @@ static int __init tintq(char *str)
__setup("tintq=", tintq);
-static int imstuckcount[2][8];
+static int imstuckcount[MAX_SMTC_VPES][8];
/* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */
-static int vpemask[2][8] = {
+static int vpemask[MAX_SMTC_VPES][8] = {
{0, 0, 1, 0, 0, 0, 0, 1},
{0, 0, 0, 0, 0, 0, 0, 1}
};
@@ -331,6 +338,22 @@ int __init smtc_build_cpu_map(int start_cpu_slot)
static void smtc_tc_setup(int vpe, int tc, int cpu)
{
+ static int cp1contexts[MAX_SMTC_VPES];
+
+ /*
+ * Make a local copy of the available FPU contexts in order
+ * to keep track of TCs that can have one.
+ */
+ if (tc == 1)
+ {
+ /*
+ * FIXME: Multi-core SMTC hasn't been tested and the
+ * maximum number of VPEs may change.
+ */
+ cp1contexts[0] = smtc_nconf1[0] - 1;
+ cp1contexts[1] = smtc_nconf1[1];
+ }
+
settc(tc);
write_tc_c0_tchalt(TCHALT_H);
mips_ihb();
@@ -343,22 +366,29 @@ static void smtc_tc_setup(int vpe, int tc, int cpu)
* an active IPI queue.
*/
write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16);
- /* Bind tc to vpe */
+
+ /* Bind TC to VPE. */
write_tc_c0_tcbind(vpe);
+
/* In general, all TCs should have the same cpu_data indications. */
memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips));
- /* For 34Kf, start with TC/CPU 0 as sole owner of single FPU context */
- if (cpu_data[0].cputype == CPU_34K ||
- cpu_data[0].cputype == CPU_1004K)
+
+ /* Check to see if there is a FPU context available for this TC. */
+ if (!cp1contexts[vpe])
cpu_data[cpu].options &= ~MIPS_CPU_FPU;
+ else
+ cp1contexts[vpe]--;
+
+ /* Store the TC and VPE into the cpu_data structure. */
cpu_data[cpu].vpe_id = vpe;
cpu_data[cpu].tc_id = tc;
- /* Multi-core SMTC hasn't been tested, but be prepared */
+
+ /* FIXME: Multi-core SMTC hasn't been tested, but be prepared. */
cpu_data[cpu].core = (read_vpe_c0_ebase() >> 1) & 0xff;
}
/*
- * Tweak to get Count registes in as close a sync as possible. The
+ * Tweak to get Count registers synced as closely as possible. The
* value seems good for 34K-class cores.
*/
@@ -466,6 +496,24 @@ void smtc_prepare_cpus(int cpus)
smtc_configure_tlb();
for (tc = 0, vpe = 0 ; (vpe < nvpe) && (tc < ntc) ; vpe++) {
+ /* Get number of CP1 contexts for each VPE. */
+ if (tc == 0)
+ {
+ /*
+ * Do not call settc() for TC0 or the FPU context
+ * value will be incorrect. Besides, we know that
+ * we are TC0 anyway.
+ */
+ smtc_nconf1[0] = ((read_vpe_c0_vpeconf1() &
+ VPECONF1_NCP1) >> VPECONF1_NCP1_SHIFT);
+ if (nvpe == 2)
+ {
+ settc(1);
+ smtc_nconf1[1] = ((read_vpe_c0_vpeconf1() &
+ VPECONF1_NCP1) >> VPECONF1_NCP1_SHIFT);
+ settc(0);
+ }
+ }
if (tcpervpe[vpe] == 0)
continue;
if (vpe != 0)
@@ -479,6 +527,18 @@ void smtc_prepare_cpus(int cpus)
*/
if (tc != 0) {
smtc_tc_setup(vpe, tc, cpu);
+ if (vpe != 0) {
+ /*
+ * Set MVP bit (possibly again). Do it
+ * here to catch CPUs that have no TCs
+ * bound to the VPE at reset. In that
+ * case, a TC must be bound to the VPE
+ * before we can set VPEControl[MVP]
+ */
+ write_vpe_c0_vpeconf0(
+ read_vpe_c0_vpeconf0() |
+ VPECONF0_MVP);
+ }
cpu++;
}
printk(" %d", tc);
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c
index c3c29354370..9be3df1fa8a 100644
--- a/arch/mips/kernel/traps.c
+++ b/arch/mips/kernel/traps.c
@@ -1253,6 +1253,7 @@ static inline void parity_protection_init(void)
case CPU_5KC:
case CPU_5KE:
+ case CPU_LOONGSON1:
write_c0_ecc(0x80000000);
back_to_back_c0_hazard();
/* Set the PE bit (bit 31) in the c0_errctl register. */
diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c
index d3bcc33f469..ce2f129b081 100644
--- a/arch/mips/lantiq/clk.c
+++ b/arch/mips/lantiq/clk.c
@@ -135,6 +135,11 @@ void clk_deactivate(struct clk *clk)
}
EXPORT_SYMBOL(clk_deactivate);
+struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
+{
+ return NULL;
+}
+
static inline u32 get_counter_resolution(void)
{
u32 res;
diff --git a/arch/mips/lantiq/prom.c b/arch/mips/lantiq/prom.c
index d185e8477fd..6cfd6117fbf 100644
--- a/arch/mips/lantiq/prom.c
+++ b/arch/mips/lantiq/prom.c
@@ -8,7 +8,10 @@
#include <linux/export.h>
#include <linux/clk.h>
+#include <linux/bootmem.h>
#include <linux/of_platform.h>
+#include <linux/of_fdt.h>
+
#include <asm/bootinfo.h>
#include <asm/time.h>
@@ -70,6 +73,25 @@ void __init plat_mem_setup(void)
__dt_setup_arch(&__dtb_start);
}
+void __init device_tree_init(void)
+{
+ unsigned long base, size;
+
+ if (!initial_boot_params)
+ return;
+
+ base = virt_to_phys((void *)initial_boot_params);
+ size = be32_to_cpu(initial_boot_params->totalsize);
+
+ /* Before we do anything, lets reserve the dt blob */
+ reserve_bootmem(base, size, BOOTMEM_DEFAULT);
+
+ unflatten_device_tree();
+
+ /* free the space reserved for the dt blob */
+ free_bootmem(base, size);
+}
+
void __init prom_init(void)
{
/* call the soc specific detetcion code and get it to fill soc_info */
diff --git a/arch/mips/lantiq/xway/sysctrl.c b/arch/mips/lantiq/xway/sysctrl.c
index 83780f7c842..befbb760ab7 100644
--- a/arch/mips/lantiq/xway/sysctrl.c
+++ b/arch/mips/lantiq/xway/sysctrl.c
@@ -20,10 +20,12 @@
/* clock control register */
#define CGU_IFCCR 0x0018
+#define CGU_IFCCR_VR9 0x0024
/* system clock register */
#define CGU_SYS 0x0010
/* pci control register */
#define CGU_PCICR 0x0034
+#define CGU_PCICR_VR9 0x0038
/* ephy configuration register */
#define CGU_EPHY 0x10
/* power control register */
@@ -80,6 +82,9 @@ static void __iomem *pmu_membase;
void __iomem *ltq_cgu_membase;
void __iomem *ltq_ebu_membase;
+static u32 ifccr = CGU_IFCCR;
+static u32 pcicr = CGU_PCICR;
+
/* legacy function kept alive to ease clkdev transition */
void ltq_pmu_enable(unsigned int module)
{
@@ -103,14 +108,14 @@ EXPORT_SYMBOL(ltq_pmu_disable);
/* enable a hw clock */
static int cgu_enable(struct clk *clk)
{
- ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) | clk->bits, CGU_IFCCR);
+ ltq_cgu_w32(ltq_cgu_r32(ifccr) | clk->bits, ifccr);
return 0;
}
/* disable a hw clock */
static void cgu_disable(struct clk *clk)
{
- ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) & ~clk->bits, CGU_IFCCR);
+ ltq_cgu_w32(ltq_cgu_r32(ifccr) & ~clk->bits, ifccr);
}
/* enable a clock gate */
@@ -138,22 +143,22 @@ static void pmu_disable(struct clk *clk)
/* the pci enable helper */
static int pci_enable(struct clk *clk)
{
- unsigned int ifccr = ltq_cgu_r32(CGU_IFCCR);
+ unsigned int val = ltq_cgu_r32(ifccr);
/* set bus clock speed */
if (of_machine_is_compatible("lantiq,ar9")) {
- ifccr &= ~0x1f00000;
+ val &= ~0x1f00000;
if (clk->rate == CLOCK_33M)
- ifccr |= 0xe00000;
+ val |= 0xe00000;
else
- ifccr |= 0x700000; /* 62.5M */
+ val |= 0x700000; /* 62.5M */
} else {
- ifccr &= ~0xf00000;
+ val &= ~0xf00000;
if (clk->rate == CLOCK_33M)
- ifccr |= 0x800000;
+ val |= 0x800000;
else
- ifccr |= 0x400000; /* 62.5M */
+ val |= 0x400000; /* 62.5M */
}
- ltq_cgu_w32(ifccr, CGU_IFCCR);
+ ltq_cgu_w32(val, ifccr);
pmu_enable(clk);
return 0;
}
@@ -161,18 +166,16 @@ static int pci_enable(struct clk *clk)
/* enable the external clock as a source */
static int pci_ext_enable(struct clk *clk)
{
- ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) & ~(1 << 16),
- CGU_IFCCR);
- ltq_cgu_w32((1 << 30), CGU_PCICR);
+ ltq_cgu_w32(ltq_cgu_r32(ifccr) & ~(1 << 16), ifccr);
+ ltq_cgu_w32((1 << 30), pcicr);
return 0;
}
/* disable the external clock as a source */
static void pci_ext_disable(struct clk *clk)
{
- ltq_cgu_w32(ltq_cgu_r32(CGU_IFCCR) | (1 << 16),
- CGU_IFCCR);
- ltq_cgu_w32((1 << 31) | (1 << 30), CGU_PCICR);
+ ltq_cgu_w32(ltq_cgu_r32(ifccr) | (1 << 16), ifccr);
+ ltq_cgu_w32((1 << 31) | (1 << 30), pcicr);
}
/* enable a clockout source */
@@ -184,11 +187,11 @@ static int clkout_enable(struct clk *clk)
for (i = 0; i < 4; i++) {
if (clk->rates[i] == clk->rate) {
int shift = 14 - (2 * clk->module);
- unsigned int ifccr = ltq_cgu_r32(CGU_IFCCR);
+ unsigned int val = ltq_cgu_r32(ifccr);
- ifccr &= ~(3 << shift);
- ifccr |= i << shift;
- ltq_cgu_w32(ifccr, CGU_IFCCR);
+ val &= ~(3 << shift);
+ val |= i << shift;
+ ltq_cgu_w32(val, ifccr);
return 0;
}
}
@@ -336,8 +339,12 @@ void __init ltq_soc_init(void)
clkdev_add_clkout();
/* add the soc dependent clocks */
- if (!of_machine_is_compatible("lantiq,vr9"))
+ if (of_machine_is_compatible("lantiq,vr9")) {
+ ifccr = CGU_IFCCR_VR9;
+ pcicr = CGU_PCICR_VR9;
+ } else {
clkdev_add_pmu("1e180000.etop", NULL, 0, PMU_PPE);
+ }
if (!of_machine_is_compatible("lantiq,ase")) {
clkdev_add_pmu("1e100c00.serial", NULL, 0, PMU_ASC1);
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index 2a7c74fc15f..399a50a541d 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -2,7 +2,7 @@
# Makefile for MIPS-specific library files..
#
-lib-y += csum_partial.o delay.o memcpy.o memcpy-inatomic.o memset.o \
+lib-y += csum_partial.o delay.o memcpy.o memset.o \
strlen_user.o strncpy_user.o strnlen_user.o uncached.o
obj-y += iomap.o
diff --git a/arch/mips/lib/memcpy-inatomic.S b/arch/mips/lib/memcpy-inatomic.S
deleted file mode 100644
index 68853a038d3..00000000000
--- a/arch/mips/lib/memcpy-inatomic.S
+++ /dev/null
@@ -1,451 +0,0 @@
-/*
- * This file is subject to the terms and conditions of the GNU General Public
- * License. See the file "COPYING" in the main directory of this archive
- * for more details.
- *
- * 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
- * Copyright (C) 2007 Maciej W. Rozycki
- *
- * Mnemonic names for arguments to memcpy/__copy_user
- */
-
-/*
- * Hack to resolve longstanding prefetch issue
- *
- * Prefetching may be fatal on some systems if we're prefetching beyond the
- * end of memory on some systems. It's also a seriously bad idea on non
- * dma-coherent systems.
- */
-#ifdef CONFIG_DMA_NONCOHERENT
-#undef CONFIG_CPU_HAS_PREFETCH
-#endif
-#ifdef CONFIG_MIPS_MALTA
-#undef CONFIG_CPU_HAS_PREFETCH
-#endif
-
-#include <asm/asm.h>
-#include <asm/asm-offsets.h>
-#include <asm/regdef.h>
-
-#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
- * include/asm-mips/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
-#ifndef CONFIG_CPU_DADDI_WORKAROUNDS
- .set noat
-#else
- .set at=v1
-#endif
-
-/*
- * 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(__copy_user_inatomic)
- /*
- * Note: dst & src may be unaligned, len may be 0
- * Temps
- */
-#define rem t8
-
- /*
- * The "issue break"s below are very approximate.
- * Issue delays for dcache fills will perturb the schedule, as will
- * load queue full replay traps, etc.
- *
- * If len < NBYTES use byte operations.
- */
- PREF( 0, 0(src) )
- PREF( 1, 0(dst) )
- sltu t2, len, NBYTES
- and t1, dst, ADDRMASK
- PREF( 0, 1*32(src) )
- PREF( 1, 1*32(dst) )
- bnez t2, .Lcopy_bytes_checklen
- and t0, src, ADDRMASK
- PREF( 0, 2*32(src) )
- PREF( 1, 2*32(dst) )
- bnez t1, .Ldst_unaligned
- nop
- bnez t0, .Lsrc_unaligned_dst_aligned
- /*
- * use delay slot for fall-through
- * src and dst are aligned; need to compute rem
- */
-.Lboth_aligned:
- SRL t0, len, LOG_NBYTES+3 # +3 for 8 units/iter
- beqz t0, .Lcleanup_both_aligned # len < 8*NBYTES
- and rem, len, (8*NBYTES-1) # rem = len % (8*NBYTES)
- PREF( 0, 3*32(src) )
- PREF( 1, 3*32(dst) )
- .align 4
-1:
-EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
-EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
-EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
-EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
- SUB len, len, 8*NBYTES
-EXC( LOAD t4, UNIT(4)(src), .Ll_exc_copy)
-EXC( LOAD t7, UNIT(5)(src), .Ll_exc_copy)
- STORE t0, UNIT(0)(dst)
- STORE t1, UNIT(1)(dst)
-EXC( LOAD t0, UNIT(6)(src), .Ll_exc_copy)
-EXC( LOAD t1, UNIT(7)(src), .Ll_exc_copy)
- ADD src, src, 8*NBYTES
- ADD dst, dst, 8*NBYTES
- STORE t2, UNIT(-6)(dst)
- STORE t3, UNIT(-5)(dst)
- STORE t4, UNIT(-4)(dst)
- STORE t7, UNIT(-3)(dst)
- STORE t0, UNIT(-2)(dst)
- STORE t1, UNIT(-1)(dst)
- PREF( 0, 8*32(src) )
- PREF( 1, 8*32(dst) )
- bne len, rem, 1b
- nop
-
- /*
- * len == rem == the number of bytes left to copy < 8*NBYTES
- */
-.Lcleanup_both_aligned:
- beqz len, .Ldone
- sltu t0, len, 4*NBYTES
- bnez t0, .Lless_than_4units
- and rem, len, (NBYTES-1) # rem = len % NBYTES
- /*
- * len >= 4*NBYTES
- */
-EXC( LOAD t0, UNIT(0)(src), .Ll_exc)
-EXC( LOAD t1, UNIT(1)(src), .Ll_exc_copy)
-EXC( LOAD t2, UNIT(2)(src), .Ll_exc_copy)
-EXC( LOAD t3, UNIT(3)(src), .Ll_exc_copy)
- SUB len, len, 4*NBYTES
- ADD src, src, 4*NBYTES
- STORE t0, UNIT(0)(dst)
- STORE t1, UNIT(1)(dst)
- STORE t2, UNIT(2)(dst)
- STORE t3, UNIT(3)(dst)
- .set reorder /* DADDI_WAR */
- ADD dst, dst, 4*NBYTES
- beqz len, .Ldone
- .set noreorder
-.Lless_than_4units:
- /*
- * rem = len % NBYTES
- */
- beq rem, len, .Lcopy_bytes
- nop
-1:
-EXC( LOAD t0, 0(src), .Ll_exc)
- ADD src, src, NBYTES
- SUB len, len, NBYTES
- STORE t0, 0(dst)
- .set reorder /* DADDI_WAR */
- ADD dst, dst, NBYTES
- bne rem, len, 1b
- .set noreorder
-
- /*
- * src and dst are aligned, need to copy rem bytes (rem < NBYTES)
- * A loop would do only a byte at a time with possible branch
- * mispredicts. Can't do an explicit LOAD dst,mask,or,STORE
- * because can't assume read-access to dst. Instead, use
- * STREST dst, which doesn't require read access to dst.
- *
- * This code should perform better than a simple loop on modern,
- * wide-issue mips processors because the code has fewer branches and
- * more instruction-level parallelism.
- */
-#define bits t2
- beqz len, .Ldone
- ADD t1, dst, len # t1 is just past last byte of dst
- li bits, 8*NBYTES
- SLL rem, len, 3 # rem = number of bits to keep
-EXC( LOAD t0, 0(src), .Ll_exc)
- SUB bits, bits, rem # bits = number of bits to discard
- SHIFT_DISCARD t0, t0, bits
- STREST t0, -1(t1)
- jr ra
- move len, zero
-.Ldst_unaligned:
- /*
- * dst is unaligned
- * t0 = src & ADDRMASK
- * t1 = dst & ADDRMASK; T1 > 0
- * len >= NBYTES
- *
- * Copy enough bytes to align dst
- * Set match = (src and dst have same alignment)
- */
-#define match rem
-EXC( LDFIRST t3, FIRST(0)(src), .Ll_exc)
- ADD t2, zero, NBYTES
-EXC( LDREST t3, REST(0)(src), .Ll_exc_copy)
- SUB t2, t2, t1 # t2 = number of bytes copied
- xor match, t0, t1
- STFIRST t3, FIRST(0)(dst)
- beq len, t2, .Ldone
- SUB len, len, t2
- ADD dst, dst, t2
- beqz match, .Lboth_aligned
- ADD src, src, t2
-
-.Lsrc_unaligned_dst_aligned:
- SRL t0, len, LOG_NBYTES+2 # +2 for 4 units/iter
- PREF( 0, 3*32(src) )
- beqz t0, .Lcleanup_src_unaligned
- and rem, len, (4*NBYTES-1) # rem = len % 4*NBYTES
- PREF( 1, 3*32(dst) )
-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), .Ll_exc)
-EXC( LDFIRST t1, FIRST(1)(src), .Ll_exc_copy)
- SUB len, len, 4*NBYTES
-EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
-EXC( LDREST t1, REST(1)(src), .Ll_exc_copy)
-EXC( LDFIRST t2, FIRST(2)(src), .Ll_exc_copy)
-EXC( LDFIRST t3, FIRST(3)(src), .Ll_exc_copy)
-EXC( LDREST t2, REST(2)(src), .Ll_exc_copy)
-EXC( LDREST t3, REST(3)(src), .Ll_exc_copy)
- PREF( 0, 9*32(src) ) # 0 is PREF_LOAD (not streamed)
- ADD src, src, 4*NBYTES
-#ifdef CONFIG_CPU_SB1
- nop # improves slotting
-#endif
- STORE t0, UNIT(0)(dst)
- STORE t1, UNIT(1)(dst)
- STORE t2, UNIT(2)(dst)
- STORE t3, UNIT(3)(dst)
- PREF( 1, 9*32(dst) ) # 1 is PREF_STORE (not streamed)
- .set reorder /* DADDI_WAR */
- ADD dst, dst, 4*NBYTES
- bne len, rem, 1b
- .set noreorder
-
-.Lcleanup_src_unaligned:
- beqz len, .Ldone
- and rem, len, NBYTES-1 # rem = len % NBYTES
- beq rem, len, .Lcopy_bytes
- nop
-1:
-EXC( LDFIRST t0, FIRST(0)(src), .Ll_exc)
-EXC( LDREST t0, REST(0)(src), .Ll_exc_copy)
- ADD src, src, NBYTES
- SUB len, len, NBYTES
- STORE t0, 0(dst)
- .set reorder /* DADDI_WAR */
- ADD dst, dst, NBYTES
- bne len, rem, 1b
- .set noreorder
-
-.Lcopy_bytes_checklen:
- beqz len, .Ldone
- nop
-.Lcopy_bytes:
- /* 0 < len < NBYTES */
-#define COPY_BYTE(N) \
-EXC( lb t0, N(src), .Ll_exc); \
- SUB len, len, 1; \
- beqz len, .Ldone; \
- sb t0, N(dst)
-
- 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), .Ll_exc)
- SUB len, len, 1
- jr ra
- sb t0, NBYTES-2(dst)
-.Ldone:
- jr ra
- nop
- END(__copy_user_inatomic)
-
-.Ll_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), .Ll_exc)
- ADD src, src, 1
- sb t1, 0(dst) # can't fault -- we're copy_from_user
- .set reorder /* DADDI_WAR */
- ADD dst, dst, 1
- bne src, t0, 1b
- .set noreorder
-.Ll_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
- jr ra
- nop
diff --git a/arch/mips/lib/memcpy.S b/arch/mips/lib/memcpy.S
index 56a1f85a1ce..65192c06781 100644
--- a/arch/mips/lib/memcpy.S
+++ b/arch/mips/lib/memcpy.S
@@ -183,6 +183,14 @@
#endif
/*
+ * t6 is used as a flag to note inatomic mode.
+ */
+LEAF(__copy_user_inatomic)
+ b __copy_user_common
+ li t6, 1
+ END(__copy_user_inatomic)
+
+/*
* A combined memcpy/__copy_user
* __copy_user sets len to 0 for success; else to an upper bound of
* the number of uncopied bytes.
@@ -193,6 +201,8 @@ LEAF(memcpy) /* a0=dst a1=src a2=len */
move v0, dst /* return value */
.L__memcpy:
FEXPORT(__copy_user)
+ li t6, 0 /* not inatomic */
+__copy_user_common:
/*
* Note: dst & src may be unaligned, len may be 0
* Temps
@@ -458,6 +468,7 @@ EXC( lb t1, 0(src), .Ll_exc)
LOAD t0, THREAD_BUADDR(t0) # t0 is just past last good address
nop
SUB len, AT, t0 # len number of uncopied bytes
+ bnez t6, .Ldone /* Skip the zeroing part if inatomic */
/*
* Here's where we rely on src and dst being incremented in tandem,
* See (3) above.
diff --git a/arch/mips/loongson/Kconfig b/arch/mips/loongson/Kconfig
index aca93eed877..263beb9322a 100644
--- a/arch/mips/loongson/Kconfig
+++ b/arch/mips/loongson/Kconfig
@@ -41,6 +41,7 @@ config LEMOTE_MACH2F
select CSRC_R4K if ! MIPS_EXTERNAL_TIMER
select DMA_NONCOHERENT
select GENERIC_ISA_DMA_SUPPORT_BROKEN
+ select HAVE_CLK
select HW_HAS_PCI
select I8259
select IRQ_CPU
diff --git a/arch/mips/loongson/lemote-2f/Makefile b/arch/mips/loongson/lemote-2f/Makefile
index 8699a53f047..4f9eaa328a1 100644
--- a/arch/mips/loongson/lemote-2f/Makefile
+++ b/arch/mips/loongson/lemote-2f/Makefile
@@ -2,7 +2,7 @@
# Makefile for lemote loongson2f family machines
#
-obj-y += machtype.o irq.o reset.o ec_kb3310b.o
+obj-y += clock.o machtype.o irq.o reset.o ec_kb3310b.o
#
# Suspend Support
diff --git a/arch/mips/kernel/cpufreq/loongson2_clock.c b/arch/mips/loongson/lemote-2f/clock.c
index 5426779d9fd..bc739d4bab2 100644
--- a/arch/mips/kernel/cpufreq/loongson2_clock.c
+++ b/arch/mips/loongson/lemote-2f/clock.c
@@ -6,14 +6,17 @@
* License. See the file "COPYING" in the main directory of this archive
* for more details.
*/
-
-#include <linux/module.h>
+#include <linux/clk.h>
#include <linux/cpufreq.h>
-#include <linux/platform_device.h>
+#include <linux/errno.h>
+#include <linux/export.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/spinlock.h>
#include <asm/clock.h>
-
-#include <loongson.h>
+#include <asm/mach-loongson/loongson.h>
static LIST_HEAD(clock_list);
static DEFINE_SPINLOCK(clock_lock);
@@ -89,12 +92,6 @@ EXPORT_SYMBOL(clk_put);
int clk_set_rate(struct clk *clk, unsigned long rate)
{
- return clk_set_rate_ex(clk, rate, 0);
-}
-EXPORT_SYMBOL_GPL(clk_set_rate);
-
-int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id)
-{
int ret = 0;
int regval;
int i;
@@ -103,7 +100,7 @@ int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id)
unsigned long flags;
spin_lock_irqsave(&clock_lock, flags);
- ret = clk->ops->set_rate(clk, rate, algo_id);
+ ret = clk->ops->set_rate(clk, rate, 0);
spin_unlock_irqrestore(&clock_lock, flags);
}
@@ -129,7 +126,7 @@ int clk_set_rate_ex(struct clk *clk, unsigned long rate, int algo_id)
return ret;
}
-EXPORT_SYMBOL_GPL(clk_set_rate_ex);
+EXPORT_SYMBOL_GPL(clk_set_rate);
long clk_round_rate(struct clk *clk, unsigned long rate)
{
@@ -146,26 +143,3 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
return rate;
}
EXPORT_SYMBOL_GPL(clk_round_rate);
-
-/*
- * This is the simple version of Loongson-2 wait, Maybe we need do this in
- * interrupt disabled content
- */
-
-DEFINE_SPINLOCK(loongson2_wait_lock);
-void loongson2_cpu_wait(void)
-{
- u32 cpu_freq;
- unsigned long flags;
-
- spin_lock_irqsave(&loongson2_wait_lock, flags);
- cpu_freq = LOONGSON_CHIPCFG0;
- LOONGSON_CHIPCFG0 &= ~0x7; /* Put CPU into wait mode */
- LOONGSON_CHIPCFG0 = cpu_freq; /* Restore CPU state */
- spin_unlock_irqrestore(&loongson2_wait_lock, flags);
-}
-EXPORT_SYMBOL_GPL(loongson2_cpu_wait);
-
-MODULE_AUTHOR("Yanhua <yanh@lemote.com>");
-MODULE_DESCRIPTION("cpufreq driver for Loongson 2F");
-MODULE_LICENSE("GPL");
diff --git a/arch/mips/loongson1/Kconfig b/arch/mips/loongson1/Kconfig
new file mode 100644
index 00000000000..a9a14d6e81a
--- /dev/null
+++ b/arch/mips/loongson1/Kconfig
@@ -0,0 +1,22 @@
+if MACH_LOONGSON1
+
+choice
+ prompt "Machine Type"
+
+config LOONGSON1_LS1B
+ bool "Loongson LS1B board"
+ select CEVT_R4K
+ select CSRC_R4K
+ select SYS_HAS_CPU_LOONGSON1B
+ select DMA_NONCOHERENT
+ select BOOT_ELF32
+ select IRQ_CPU
+ select SYS_SUPPORTS_32BIT_KERNEL
+ select SYS_SUPPORTS_LITTLE_ENDIAN
+ select SYS_SUPPORTS_HIGHMEM
+ select SYS_HAS_EARLY_PRINTK
+ select HAVE_CLK
+
+endchoice
+
+endif # MACH_LOONGSON1
diff --git a/arch/mips/loongson1/Makefile b/arch/mips/loongson1/Makefile
new file mode 100644
index 00000000000..9719c75886f
--- /dev/null
+++ b/arch/mips/loongson1/Makefile
@@ -0,0 +1,11 @@
+#
+# Common code for all Loongson 1 based systems
+#
+
+obj-$(CONFIG_MACH_LOONGSON1) += common/
+
+#
+# Loongson LS1B board
+#
+
+obj-$(CONFIG_LOONGSON1_LS1B) += ls1b/
diff --git a/arch/mips/loongson1/Platform b/arch/mips/loongson1/Platform
new file mode 100644
index 00000000000..99bdefe627a
--- /dev/null
+++ b/arch/mips/loongson1/Platform
@@ -0,0 +1,7 @@
+cflags-$(CONFIG_CPU_LOONGSON1) += \
+ $(call cc-option,-march=mips32r2,-mips32r2 -U_MIPS_ISA -D_MIPS_ISA=_MIPS_ISA_MIPS32) \
+ -Wa,-mips32r2 -Wa,--trap
+
+platform-$(CONFIG_MACH_LOONGSON1) += loongson1/
+cflags-$(CONFIG_MACH_LOONGSON1) += -I$(srctree)/arch/mips/include/asm/mach-loongson1
+load-$(CONFIG_LOONGSON1_LS1B) += 0xffffffff80100000
diff --git a/arch/mips/loongson1/common/Makefile b/arch/mips/loongson1/common/Makefile
new file mode 100644
index 00000000000..b2797709ef5
--- /dev/null
+++ b/arch/mips/loongson1/common/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for common code of loongson1 based machines.
+#
+
+obj-y += clock.o irq.o platform.o prom.o reset.o setup.o
diff --git a/arch/mips/loongson1/common/clock.c b/arch/mips/loongson1/common/clock.c
new file mode 100644
index 00000000000..1bbbbec1208
--- /dev/null
+++ b/arch/mips/loongson1/common/clock.c
@@ -0,0 +1,181 @@
+/*
+ * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <asm/clock.h>
+#include <asm/time.h>
+
+#include <loongson1.h>
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+
+struct clk *clk_get(struct device *dev, const char *name)
+{
+ struct clk *c;
+ struct clk *ret = NULL;
+
+ mutex_lock(&clocks_mutex);
+ list_for_each_entry(c, &clocks, node) {
+ if (!strcmp(c->name, name)) {
+ ret = c;
+ break;
+ }
+ }
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_get);
+
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+void clk_put(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_put);
+
+static void pll_clk_init(struct clk *clk)
+{
+ u32 pll;
+
+ pll = __raw_readl(LS1X_CLK_PLL_FREQ);
+ clk->rate = (12 + (pll & 0x3f)) * 33 / 2
+ + ((pll >> 8) & 0x3ff) * 33 / 1024 / 2;
+ clk->rate *= 1000000;
+}
+
+static void cpu_clk_init(struct clk *clk)
+{
+ u32 pll, ctrl;
+
+ pll = clk_get_rate(clk->parent);
+ ctrl = __raw_readl(LS1X_CLK_PLL_DIV) & DIV_CPU;
+ clk->rate = pll / (ctrl >> DIV_CPU_SHIFT);
+}
+
+static void ddr_clk_init(struct clk *clk)
+{
+ u32 pll, ctrl;
+
+ pll = clk_get_rate(clk->parent);
+ ctrl = __raw_readl(LS1X_CLK_PLL_DIV) & DIV_DDR;
+ clk->rate = pll / (ctrl >> DIV_DDR_SHIFT);
+}
+
+static void dc_clk_init(struct clk *clk)
+{
+ u32 pll, ctrl;
+
+ pll = clk_get_rate(clk->parent);
+ ctrl = __raw_readl(LS1X_CLK_PLL_DIV) & DIV_DC;
+ clk->rate = pll / (ctrl >> DIV_DC_SHIFT);
+}
+
+static struct clk_ops pll_clk_ops = {
+ .init = pll_clk_init,
+};
+
+static struct clk_ops cpu_clk_ops = {
+ .init = cpu_clk_init,
+};
+
+static struct clk_ops ddr_clk_ops = {
+ .init = ddr_clk_init,
+};
+
+static struct clk_ops dc_clk_ops = {
+ .init = dc_clk_init,
+};
+
+static struct clk pll_clk = {
+ .name = "pll",
+ .ops = &pll_clk_ops,
+};
+
+static struct clk cpu_clk = {
+ .name = "cpu",
+ .parent = &pll_clk,
+ .ops = &cpu_clk_ops,
+};
+
+static struct clk ddr_clk = {
+ .name = "ddr",
+ .parent = &pll_clk,
+ .ops = &ddr_clk_ops,
+};
+
+static struct clk dc_clk = {
+ .name = "dc",
+ .parent = &pll_clk,
+ .ops = &dc_clk_ops,
+};
+
+int clk_register(struct clk *clk)
+{
+ mutex_lock(&clocks_mutex);
+ list_add(&clk->node, &clocks);
+ if (clk->ops->init)
+ clk->ops->init(clk);
+ mutex_unlock(&clocks_mutex);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_register);
+
+static struct clk *ls1x_clks[] = {
+ &pll_clk,
+ &cpu_clk,
+ &ddr_clk,
+ &dc_clk,
+};
+
+int __init ls1x_clock_init(void)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(ls1x_clks); i++)
+ clk_register(ls1x_clks[i]);
+
+ return 0;
+}
+
+void __init plat_time_init(void)
+{
+ struct clk *clk;
+
+ /* Initialize LS1X clocks */
+ ls1x_clock_init();
+
+ /* setup mips r4k timer */
+ clk = clk_get(NULL, "cpu");
+ if (IS_ERR(clk))
+ panic("unable to get dc clock, err=%ld", PTR_ERR(clk));
+
+ mips_hpt_frequency = clk_get_rate(clk) / 2;
+}
diff --git a/arch/mips/loongson1/common/irq.c b/arch/mips/loongson1/common/irq.c
new file mode 100644
index 00000000000..41bc8ffe7bb
--- /dev/null
+++ b/arch/mips/loongson1/common/irq.c
@@ -0,0 +1,147 @@
+/*
+ * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <asm/irq_cpu.h>
+
+#include <loongson1.h>
+#include <irq.h>
+
+#define LS1X_INTC_REG(n, x) \
+ ((void __iomem *)KSEG1ADDR(LS1X_INTC_BASE + (n * 0x18) + (x)))
+
+#define LS1X_INTC_INTISR(n) LS1X_INTC_REG(n, 0x0)
+#define LS1X_INTC_INTIEN(n) LS1X_INTC_REG(n, 0x4)
+#define LS1X_INTC_INTSET(n) LS1X_INTC_REG(n, 0x8)
+#define LS1X_INTC_INTCLR(n) LS1X_INTC_REG(n, 0xc)
+#define LS1X_INTC_INTPOL(n) LS1X_INTC_REG(n, 0x10)
+#define LS1X_INTC_INTEDGE(n) LS1X_INTC_REG(n, 0x14)
+
+static void ls1x_irq_ack(struct irq_data *d)
+{
+ unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f;
+ unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5;
+
+ __raw_writel(__raw_readl(LS1X_INTC_INTCLR(n))
+ | (1 << bit), LS1X_INTC_INTCLR(n));
+}
+
+static void ls1x_irq_mask(struct irq_data *d)
+{
+ unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f;
+ unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5;
+
+ __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n))
+ & ~(1 << bit), LS1X_INTC_INTIEN(n));
+}
+
+static void ls1x_irq_mask_ack(struct irq_data *d)
+{
+ unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f;
+ unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5;
+
+ __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n))
+ & ~(1 << bit), LS1X_INTC_INTIEN(n));
+ __raw_writel(__raw_readl(LS1X_INTC_INTCLR(n))
+ | (1 << bit), LS1X_INTC_INTCLR(n));
+}
+
+static void ls1x_irq_unmask(struct irq_data *d)
+{
+ unsigned int bit = (d->irq - LS1X_IRQ_BASE) & 0x1f;
+ unsigned int n = (d->irq - LS1X_IRQ_BASE) >> 5;
+
+ __raw_writel(__raw_readl(LS1X_INTC_INTIEN(n))
+ | (1 << bit), LS1X_INTC_INTIEN(n));
+}
+
+static struct irq_chip ls1x_irq_chip = {
+ .name = "LS1X-INTC",
+ .irq_ack = ls1x_irq_ack,
+ .irq_mask = ls1x_irq_mask,
+ .irq_mask_ack = ls1x_irq_mask_ack,
+ .irq_unmask = ls1x_irq_unmask,
+};
+
+static void ls1x_irq_dispatch(int n)
+{
+ u32 int_status, irq;
+
+ /* Get pending sources, masked by current enables */
+ int_status = __raw_readl(LS1X_INTC_INTISR(n)) &
+ __raw_readl(LS1X_INTC_INTIEN(n));
+
+ if (int_status) {
+ irq = LS1X_IRQ(n, __ffs(int_status));
+ do_IRQ(irq);
+ }
+}
+
+asmlinkage void plat_irq_dispatch(void)
+{
+ unsigned int pending;
+
+ pending = read_c0_cause() & read_c0_status() & ST0_IM;
+
+ if (pending & CAUSEF_IP7)
+ do_IRQ(TIMER_IRQ);
+ else if (pending & CAUSEF_IP2)
+ ls1x_irq_dispatch(0); /* INT0 */
+ else if (pending & CAUSEF_IP3)
+ ls1x_irq_dispatch(1); /* INT1 */
+ else if (pending & CAUSEF_IP4)
+ ls1x_irq_dispatch(2); /* INT2 */
+ else if (pending & CAUSEF_IP5)
+ ls1x_irq_dispatch(3); /* INT3 */
+ else if (pending & CAUSEF_IP6)
+ ls1x_irq_dispatch(4); /* INT4 */
+ else
+ spurious_interrupt();
+
+}
+
+struct irqaction cascade_irqaction = {
+ .handler = no_action,
+ .name = "cascade",
+ .flags = IRQF_NO_THREAD,
+};
+
+static void __init ls1x_irq_init(int base)
+{
+ int n;
+
+ /* Disable interrupts and clear pending,
+ * setup all IRQs as high level triggered
+ */
+ for (n = 0; n < 4; n++) {
+ __raw_writel(0x0, LS1X_INTC_INTIEN(n));
+ __raw_writel(0xffffffff, LS1X_INTC_INTCLR(n));
+ __raw_writel(0xffffffff, LS1X_INTC_INTPOL(n));
+ /* set DMA0, DMA1 and DMA2 to edge trigger */
+ __raw_writel(n ? 0x0 : 0xe000, LS1X_INTC_INTEDGE(n));
+ }
+
+
+ for (n = base; n < LS1X_IRQS; n++) {
+ irq_set_chip_and_handler(n, &ls1x_irq_chip,
+ handle_level_irq);
+ }
+
+ setup_irq(INT0_IRQ, &cascade_irqaction);
+ setup_irq(INT1_IRQ, &cascade_irqaction);
+ setup_irq(INT2_IRQ, &cascade_irqaction);
+ setup_irq(INT3_IRQ, &cascade_irqaction);
+}
+
+void __init arch_init_irq(void)
+{
+ mips_cpu_irq_init();
+ ls1x_irq_init(LS1X_IRQ_BASE);
+}
diff --git a/arch/mips/loongson1/common/platform.c b/arch/mips/loongson1/common/platform.c
new file mode 100644
index 00000000000..e92d59c4bd7
--- /dev/null
+++ b/arch/mips/loongson1/common/platform.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/clk.h>
+#include <linux/dma-mapping.h>
+#include <linux/err.h>
+#include <linux/phy.h>
+#include <linux/serial_8250.h>
+#include <linux/stmmac.h>
+#include <asm-generic/sizes.h>
+
+#include <loongson1.h>
+
+#define LS1X_UART(_id) \
+ { \
+ .mapbase = LS1X_UART ## _id ## _BASE, \
+ .irq = LS1X_UART ## _id ## _IRQ, \
+ .iotype = UPIO_MEM, \
+ .flags = UPF_IOREMAP | UPF_FIXED_TYPE, \
+ .type = PORT_16550A, \
+ }
+
+static struct plat_serial8250_port ls1x_serial8250_port[] = {
+ LS1X_UART(0),
+ LS1X_UART(1),
+ LS1X_UART(2),
+ LS1X_UART(3),
+ {},
+};
+
+struct platform_device ls1x_uart_device = {
+ .name = "serial8250",
+ .id = PLAT8250_DEV_PLATFORM,
+ .dev = {
+ .platform_data = ls1x_serial8250_port,
+ },
+};
+
+void __init ls1x_serial_setup(void)
+{
+ struct clk *clk;
+ struct plat_serial8250_port *p;
+
+ clk = clk_get(NULL, "dc");
+ if (IS_ERR(clk))
+ panic("unable to get dc clock, err=%ld", PTR_ERR(clk));
+
+ for (p = ls1x_serial8250_port; p->flags != 0; ++p)
+ p->uartclk = clk_get_rate(clk);
+}
+
+/* Synopsys Ethernet GMAC */
+static struct resource ls1x_eth0_resources[] = {
+ [0] = {
+ .start = LS1X_GMAC0_BASE,
+ .end = LS1X_GMAC0_BASE + SZ_64K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .name = "macirq",
+ .start = LS1X_GMAC0_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct stmmac_mdio_bus_data ls1x_mdio_bus_data = {
+ .bus_id = 0,
+ .phy_mask = 0,
+};
+
+static struct plat_stmmacenet_data ls1x_eth_data = {
+ .bus_id = 0,
+ .phy_addr = -1,
+ .mdio_bus_data = &ls1x_mdio_bus_data,
+ .has_gmac = 1,
+ .tx_coe = 1,
+};
+
+struct platform_device ls1x_eth0_device = {
+ .name = "stmmaceth",
+ .id = 0,
+ .num_resources = ARRAY_SIZE(ls1x_eth0_resources),
+ .resource = ls1x_eth0_resources,
+ .dev = {
+ .platform_data = &ls1x_eth_data,
+ },
+};
+
+/* USB EHCI */
+static u64 ls1x_ehci_dmamask = DMA_BIT_MASK(32);
+
+static struct resource ls1x_ehci_resources[] = {
+ [0] = {
+ .start = LS1X_EHCI_BASE,
+ .end = LS1X_EHCI_BASE + SZ_32K - 1,
+ .flags = IORESOURCE_MEM,
+ },
+ [1] = {
+ .start = LS1X_EHCI_IRQ,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+struct platform_device ls1x_ehci_device = {
+ .name = "ls1x-ehci",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(ls1x_ehci_resources),
+ .resource = ls1x_ehci_resources,
+ .dev = {
+ .dma_mask = &ls1x_ehci_dmamask,
+ },
+};
+
+/* Real Time Clock */
+struct platform_device ls1x_rtc_device = {
+ .name = "ls1x-rtc",
+ .id = -1,
+};
diff --git a/arch/mips/loongson1/common/prom.c b/arch/mips/loongson1/common/prom.c
new file mode 100644
index 00000000000..1f8e49f9886
--- /dev/null
+++ b/arch/mips/loongson1/common/prom.c
@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
+ *
+ * Modified from arch/mips/pnx833x/common/prom.c.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/serial_reg.h>
+#include <asm/bootinfo.h>
+
+#include <loongson1.h>
+#include <prom.h>
+
+int prom_argc;
+char **prom_argv, **prom_envp;
+unsigned long memsize, highmemsize;
+
+char *prom_getenv(char *envname)
+{
+ char **env = prom_envp;
+ int i;
+
+ i = strlen(envname);
+
+ while (*env) {
+ if (strncmp(envname, *env, i) == 0 && *(*env+i) == '=')
+ return *env + i + 1;
+ env++;
+ }
+
+ return 0;
+}
+
+static inline unsigned long env_or_default(char *env, unsigned long dfl)
+{
+ char *str = prom_getenv(env);
+ return str ? simple_strtol(str, 0, 0) : dfl;
+}
+
+void __init prom_init_cmdline(void)
+{
+ char *c = &(arcs_cmdline[0]);
+ int i;
+
+ for (i = 1; i < prom_argc; i++) {
+ strcpy(c, prom_argv[i]);
+ c += strlen(prom_argv[i]);
+ if (i < prom_argc-1)
+ *c++ = ' ';
+ }
+ *c = 0;
+}
+
+void __init prom_init(void)
+{
+ prom_argc = fw_arg0;
+ prom_argv = (char **)fw_arg1;
+ prom_envp = (char **)fw_arg2;
+
+ prom_init_cmdline();
+
+ memsize = env_or_default("memsize", DEFAULT_MEMSIZE);
+ highmemsize = env_or_default("highmemsize", 0x0);
+}
+
+void __init prom_free_prom_memory(void)
+{
+}
+
+#define PORT(offset) (u8 *)(KSEG1ADDR(LS1X_UART0_BASE + offset))
+
+void __init prom_putchar(char c)
+{
+ int timeout;
+
+ timeout = 1024;
+
+ while (((readb(PORT(UART_LSR)) & UART_LSR_THRE) == 0)
+ && (timeout-- > 0))
+ ;
+
+ writeb(c, PORT(UART_TX));
+}
diff --git a/arch/mips/loongson1/common/reset.c b/arch/mips/loongson1/common/reset.c
new file mode 100644
index 00000000000..fb979a784ec
--- /dev/null
+++ b/arch/mips/loongson1/common/reset.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <linux/io.h>
+#include <linux/pm.h>
+#include <asm/reboot.h>
+
+#include <loongson1.h>
+
+static void ls1x_restart(char *command)
+{
+ __raw_writel(0x1, LS1X_WDT_EN);
+ __raw_writel(0x5000000, LS1X_WDT_TIMER);
+ __raw_writel(0x1, LS1X_WDT_SET);
+}
+
+static void ls1x_halt(void)
+{
+ while (1) {
+ if (cpu_wait)
+ cpu_wait();
+ }
+}
+
+static void ls1x_power_off(void)
+{
+ ls1x_halt();
+}
+
+static int __init ls1x_reboot_setup(void)
+{
+ _machine_restart = ls1x_restart;
+ _machine_halt = ls1x_halt;
+ pm_power_off = ls1x_power_off;
+
+ return 0;
+}
+
+arch_initcall(ls1x_reboot_setup);
diff --git a/arch/mips/loongson1/common/setup.c b/arch/mips/loongson1/common/setup.c
new file mode 100644
index 00000000000..62128cc27e6
--- /dev/null
+++ b/arch/mips/loongson1/common/setup.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <asm/bootinfo.h>
+
+#include <prom.h>
+
+void __init plat_mem_setup(void)
+{
+ add_memory_region(0x0, (memsize << 20), BOOT_MEM_RAM);
+}
+
+const char *get_system_type(void)
+{
+ unsigned int processor_id = (&current_cpu_data)->processor_id;
+
+ switch (processor_id & PRID_REV_MASK) {
+ case PRID_REV_LOONGSON1B:
+ return "LOONGSON LS1B";
+ default:
+ return "LOONGSON (unknown)";
+ }
+}
diff --git a/arch/mips/loongson1/ls1b/Makefile b/arch/mips/loongson1/ls1b/Makefile
new file mode 100644
index 00000000000..891eac482b8
--- /dev/null
+++ b/arch/mips/loongson1/ls1b/Makefile
@@ -0,0 +1,5 @@
+#
+# Makefile for loongson1B based machines.
+#
+
+obj-y += board.o
diff --git a/arch/mips/loongson1/ls1b/board.c b/arch/mips/loongson1/ls1b/board.c
new file mode 100644
index 00000000000..295b1be893e
--- /dev/null
+++ b/arch/mips/loongson1/ls1b/board.c
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2011 Zhang, Keguang <keguang.zhang@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ */
+
+#include <platform.h>
+
+#include <linux/serial_8250.h>
+#include <loongson1.h>
+
+static struct platform_device *ls1b_platform_devices[] __initdata = {
+ &ls1x_uart_device,
+ &ls1x_eth0_device,
+ &ls1x_ehci_device,
+ &ls1x_rtc_device,
+};
+
+static int __init ls1b_platform_init(void)
+{
+ int err;
+
+ ls1x_serial_setup();
+
+ err = platform_add_devices(ls1b_platform_devices,
+ ARRAY_SIZE(ls1b_platform_devices));
+ return err;
+}
+
+arch_initcall(ls1b_platform_init);
diff --git a/arch/mips/mm/uasm.c b/arch/mips/mm/uasm.c
index 5fa185151fc..64a28e81906 100644
--- a/arch/mips/mm/uasm.c
+++ b/arch/mips/mm/uasm.c
@@ -58,18 +58,16 @@ enum fields {
enum opcode {
insn_invalid,
- insn_addu, insn_addiu, insn_and, insn_andi, insn_beq,
- insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
- insn_bne, insn_cache, insn_daddu, insn_daddiu, insn_dmfc0,
- insn_dmtc0, insn_dsll, insn_dsll32, insn_dsra, insn_dsrl,
- insn_dsrl32, insn_drotr, insn_drotr32, insn_dsubu, insn_eret,
- insn_j, insn_jal, insn_jr, insn_ld, insn_ll, insn_lld,
- insn_lui, insn_lw, insn_mfc0, insn_mtc0, insn_or, insn_ori,
- insn_pref, insn_rfe, insn_sc, insn_scd, insn_sd, insn_sll,
- insn_sra, insn_srl, insn_rotr, insn_subu, insn_sw, insn_tlbp,
+ insn_addiu, insn_addu, insn_and, insn_andi, insn_bbit0, insn_bbit1,
+ insn_beq, insn_beql, insn_bgez, insn_bgezl, insn_bltz, insn_bltzl,
+ insn_bne, insn_cache, insn_daddiu, insn_daddu, insn_dins, insn_dinsm,
+ insn_dmfc0, insn_dmtc0, insn_drotr, insn_drotr32, insn_dsll,
+ insn_dsll32, insn_dsra, insn_dsrl, insn_dsrl32, insn_dsubu, insn_eret,
+ insn_j, insn_jal, insn_jr, insn_ld, insn_ldx, insn_ll, insn_lld,
+ insn_lui, insn_lw, insn_lwx, insn_mfc0, insn_mtc0, insn_or, insn_ori,
+ insn_pref, insn_rfe, insn_rotr, insn_sc, insn_scd, insn_sd, insn_sll,
+ insn_sra, insn_srl, insn_subu, insn_sw, insn_syscall, insn_tlbp,
insn_tlbr, insn_tlbwi, insn_tlbwr, insn_xor, insn_xori,
- insn_dins, insn_dinsm, insn_syscall, insn_bbit0, insn_bbit1,
- insn_lwx, insn_ldx
};
struct insn {
@@ -90,65 +88,65 @@ struct insn {
static struct insn insn_table[] __uasminitdata = {
{ insn_addiu, M(addiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
{ insn_addu, M(spec_op, 0, 0, 0, 0, addu_op), RS | RT | RD },
- { insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD },
{ insn_andi, M(andi_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
- { insn_beq, M(beq_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
+ { insn_and, M(spec_op, 0, 0, 0, 0, and_op), RS | RT | RD },
+ { insn_bbit0, M(lwc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
+ { insn_bbit1, M(swc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
{ insn_beql, M(beql_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
- { insn_bgez, M(bcond_op, 0, bgez_op, 0, 0, 0), RS | BIMM },
+ { insn_beq, M(beq_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
{ insn_bgezl, M(bcond_op, 0, bgezl_op, 0, 0, 0), RS | BIMM },
- { insn_bltz, M(bcond_op, 0, bltz_op, 0, 0, 0), RS | BIMM },
+ { insn_bgez, M(bcond_op, 0, bgez_op, 0, 0, 0), RS | BIMM },
{ insn_bltzl, M(bcond_op, 0, bltzl_op, 0, 0, 0), RS | BIMM },
+ { insn_bltz, M(bcond_op, 0, bltz_op, 0, 0, 0), RS | BIMM },
{ insn_bne, M(bne_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
{ insn_cache, M(cache_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
{ insn_daddiu, M(daddiu_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
{ insn_daddu, M(spec_op, 0, 0, 0, 0, daddu_op), RS | RT | RD },
+ { insn_dinsm, M(spec3_op, 0, 0, 0, 0, dinsm_op), RS | RT | RD | RE },
+ { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE },
{ insn_dmfc0, M(cop0_op, dmfc_op, 0, 0, 0, 0), RT | RD | SET},
{ insn_dmtc0, M(cop0_op, dmtc_op, 0, 0, 0, 0), RT | RD | SET},
- { insn_dsll, M(spec_op, 0, 0, 0, 0, dsll_op), RT | RD | RE },
+ { insn_drotr32, M(spec_op, 1, 0, 0, 0, dsrl32_op), RT | RD | RE },
+ { insn_drotr, M(spec_op, 1, 0, 0, 0, dsrl_op), RT | RD | RE },
{ insn_dsll32, M(spec_op, 0, 0, 0, 0, dsll32_op), RT | RD | RE },
+ { insn_dsll, M(spec_op, 0, 0, 0, 0, dsll_op), RT | RD | RE },
{ insn_dsra, M(spec_op, 0, 0, 0, 0, dsra_op), RT | RD | RE },
- { insn_dsrl, M(spec_op, 0, 0, 0, 0, dsrl_op), RT | RD | RE },
{ insn_dsrl32, M(spec_op, 0, 0, 0, 0, dsrl32_op), RT | RD | RE },
- { insn_drotr, M(spec_op, 1, 0, 0, 0, dsrl_op), RT | RD | RE },
- { insn_drotr32, M(spec_op, 1, 0, 0, 0, dsrl32_op), RT | RD | RE },
+ { insn_dsrl, M(spec_op, 0, 0, 0, 0, dsrl_op), RT | RD | RE },
{ insn_dsubu, M(spec_op, 0, 0, 0, 0, dsubu_op), RS | RT | RD },
{ insn_eret, M(cop0_op, cop_op, 0, 0, 0, eret_op), 0 },
- { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM },
{ insn_jal, M(jal_op, 0, 0, 0, 0, 0), JIMM },
+ { insn_j, M(j_op, 0, 0, 0, 0, 0), JIMM },
{ insn_jr, M(spec_op, 0, 0, 0, 0, jr_op), RS },
{ insn_ld, M(ld_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
- { insn_ll, M(ll_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_ldx, M(spec3_op, 0, 0, 0, ldx_op, lx_op), RS | RT | RD },
{ insn_lld, M(lld_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_ll, M(ll_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
{ insn_lui, M(lui_op, 0, 0, 0, 0, 0), RT | SIMM },
{ insn_lw, M(lw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD },
{ insn_mfc0, M(cop0_op, mfc_op, 0, 0, 0, 0), RT | RD | SET},
{ insn_mtc0, M(cop0_op, mtc_op, 0, 0, 0, 0), RT | RD | SET},
- { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD },
{ insn_ori, M(ori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
+ { insn_or, M(spec_op, 0, 0, 0, 0, or_op), RS | RT | RD },
{ insn_pref, M(pref_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
{ insn_rfe, M(cop0_op, cop_op, 0, 0, 0, rfe_op), 0 },
- { insn_sc, M(sc_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_rotr, M(spec_op, 1, 0, 0, 0, srl_op), RT | RD | RE },
{ insn_scd, M(scd_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_sc, M(sc_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
{ insn_sd, M(sd_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
{ insn_sll, M(spec_op, 0, 0, 0, 0, sll_op), RT | RD | RE },
{ insn_sra, M(spec_op, 0, 0, 0, 0, sra_op), RT | RD | RE },
{ insn_srl, M(spec_op, 0, 0, 0, 0, srl_op), RT | RD | RE },
- { insn_rotr, M(spec_op, 1, 0, 0, 0, srl_op), RT | RD | RE },
{ insn_subu, M(spec_op, 0, 0, 0, 0, subu_op), RS | RT | RD },
{ insn_sw, M(sw_op, 0, 0, 0, 0, 0), RS | RT | SIMM },
+ { insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM},
{ insn_tlbp, M(cop0_op, cop_op, 0, 0, 0, tlbp_op), 0 },
{ insn_tlbr, M(cop0_op, cop_op, 0, 0, 0, tlbr_op), 0 },
{ insn_tlbwi, M(cop0_op, cop_op, 0, 0, 0, tlbwi_op), 0 },
{ insn_tlbwr, M(cop0_op, cop_op, 0, 0, 0, tlbwr_op), 0 },
- { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD },
{ insn_xori, M(xori_op, 0, 0, 0, 0, 0), RS | RT | UIMM },
- { insn_dins, M(spec3_op, 0, 0, 0, 0, dins_op), RS | RT | RD | RE },
- { insn_dinsm, M(spec3_op, 0, 0, 0, 0, dinsm_op), RS | RT | RD | RE },
- { insn_syscall, M(spec_op, 0, 0, 0, 0, syscall_op), SCIMM},
- { insn_bbit0, M(lwc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
- { insn_bbit1, M(swc2_op, 0, 0, 0, 0, 0), RS | RT | BIMM },
- { insn_lwx, M(spec3_op, 0, 0, 0, lwx_op, lx_op), RS | RT | RD },
- { insn_ldx, M(spec3_op, 0, 0, 0, ldx_op, lx_op), RS | RT | RD },
+ { insn_xor, M(spec_op, 0, 0, 0, 0, xor_op), RS | RT | RD },
{ insn_invalid, 0, 0 }
};
diff --git a/arch/mips/netlogic/common/earlycons.c b/arch/mips/netlogic/common/earlycons.c
index f193f7b3bd8..1902fa22d27 100644
--- a/arch/mips/netlogic/common/earlycons.c
+++ b/arch/mips/netlogic/common/earlycons.c
@@ -54,7 +54,7 @@ void prom_putchar(char c)
#elif defined(CONFIG_CPU_XLR)
uartbase = nlm_mmio_base(NETLOGIC_IO_UART_0_OFFSET);
#endif
- while (nlm_read_reg(uartbase, UART_LSR) == 0)
+ while ((nlm_read_reg(uartbase, UART_LSR) & UART_LSR_THRE) == 0)
;
nlm_write_reg(uartbase, UART_TX, c);
}
diff --git a/arch/mips/netlogic/common/smpboot.S b/arch/mips/netlogic/common/smpboot.S
index c138b1a6dec..a13355cc97e 100644
--- a/arch/mips/netlogic/common/smpboot.S
+++ b/arch/mips/netlogic/common/smpboot.S
@@ -54,28 +54,68 @@
XLP_IO_SYS_OFFSET(node) + XLP_IO_PCI_HDRSZ + \
SYS_CPU_NONCOHERENT_MODE * 4
-.macro __config_lsu
- li t0, LSU_DEFEATURE
- mfcr t1, t0
+#define XLP_AX_WORKAROUND /* enable Ax silicon workarounds */
- lui t2, 0x4080 /* Enable Unaligned Access, L2HPE */
- or t1, t1, t2
- li t2, ~0xe /* S1RCM */
+/* Enable XLP features and workarounds in the LSU */
+.macro xlp_config_lsu
+ li t0, LSU_DEFEATURE
+ mfcr t1, t0
+
+ lui t2, 0x4080 /* Enable Unaligned Access, L2HPE */
+ or t1, t1, t2
+#ifdef XLP_AX_WORKAROUND
+ li t2, ~0xe /* S1RCM */
and t1, t1, t2
- mtcr t1, t0
+#endif
+ mtcr t1, t0
- li t0, SCHED_DEFEATURE
- lui t1, 0x0100 /* Experimental: Disable BRU accepting ALU ops */
- mtcr t1, t0
+#ifdef XLP_AX_WORKAROUND
+ li t0, SCHED_DEFEATURE
+ lui t1, 0x0100 /* Disable BRU accepting ALU ops */
+ mtcr t1, t0
+#endif
+.endm
+
+/*
+ * This is the code that will be copied to the reset entry point for
+ * XLR and XLP. The XLP cores start here when they are woken up. This
+ * is also the NMI entry point.
+ */
+.macro xlp_flush_l1_dcache
+ li t0, LSU_DEBUG_DATA0
+ li t1, LSU_DEBUG_ADDR
+ li t2, 0 /* index */
+ li t3, 0x1000 /* loop count */
+1:
+ sll v0, t2, 5
+ mtcr zero, t0
+ ori v1, v0, 0x3 /* way0 | write_enable | write_active */
+ mtcr v1, t1
+2:
+ mfcr v1, t1
+ andi v1, 0x1 /* wait for write_active == 0 */
+ bnez v1, 2b
+ nop
+ mtcr zero, t0
+ ori v1, v0, 0x7 /* way1 | write_enable | write_active */
+ mtcr v1, t1
+3:
+ mfcr v1, t1
+ andi v1, 0x1 /* wait for write_active == 0 */
+ bnez v1, 3b
+ nop
+ addi t2, 1
+ bne t3, t2, 1b
+ nop
.endm
/*
* The cores can come start when they are woken up. This is also the NMI
* entry, so check that first.
*
- * The data corresponding to reset is stored at RESET_DATA_PHYS location,
- * this will have the thread mask (used when core is woken up) and the
- * current NMI handler in case we reached here for an NMI.
+ * The data corresponding to reset/NMI is stored at RESET_DATA_PHYS
+ * location, this will have the thread mask (used when core is woken up)
+ * and the current NMI handler in case we reached here for an NMI.
*
* When a core or thread is newly woken up, it loops in a 'wait'. When
* the CPU really needs waking up, we send an NMI to it, with the NMI
@@ -89,12 +129,12 @@
FEXPORT(nlm_reset_entry)
dmtc0 k0, $22, 6
dmtc0 k1, $22, 7
- mfc0 k0, CP0_STATUS
- li k1, 0x80000
- and k1, k0, k1
- beqz k1, 1f /* go to real reset entry */
+ mfc0 k0, CP0_STATUS
+ li k1, 0x80000
+ and k1, k0, k1
+ beqz k1, 1f /* go to real reset entry */
nop
- li k1, CKSEG1ADDR(RESET_DATA_PHYS) /* NMI */
+ li k1, CKSEG1ADDR(RESET_DATA_PHYS) /* NMI */
ld k0, BOOT_NMI_HANDLER(k1)
jr k0
nop
@@ -114,21 +154,25 @@ FEXPORT(nlm_reset_entry)
li t2, SYS_CPU_COHERENT_BASE(0)
add t2, t2, t3 /* t2 <- SYS offset for node */
lw t1, 0(t2)
- and t1, t1, t0
- sw t1, 0(t2)
+ and t1, t1, t0
+ sw t1, 0(t2)
/* read back to ensure complete */
- lw t1, 0(t2)
+ lw t1, 0(t2)
sync
/* Configure LSU on Non-0 Cores. */
- __config_lsu
+ xlp_config_lsu
+ /* FALL THROUGH */
/*
* Wake up sibling threads from the initial thread in
* a core.
*/
EXPORT(nlm_boot_siblings)
+ /* core L1D flush before enable threads */
+ xlp_flush_l1_dcache
+ /* Enable hw threads by writing to MAP_THREADMODE of the core */
li t0, CKSEG1ADDR(RESET_DATA_PHYS)
lw t1, BOOT_THREAD_MODE(t0) /* t1 <- thread mode */
li t0, ((CPU_BLOCKID_MAP << 8) | MAP_THREADMODE)
@@ -139,31 +183,28 @@ EXPORT(nlm_boot_siblings)
/*
* The new hardware thread starts at the next instruction
* For all the cases other than core 0 thread 0, we will
- * jump to the secondary wait function.
- */
+ * jump to the secondary wait function.
+ */
mfc0 v0, CP0_EBASE, 1
andi v0, 0x7f /* v0 <- node/core */
-#if 1
- /* A0 errata - Write MMU_SETUP after changing thread mode register. */
+ /* Init MMU in the first thread after changing THREAD_MODE
+ * register (Ax Errata?)
+ */
andi v1, v0, 0x3 /* v1 <- thread id */
bnez v1, 2f
nop
- li t0, MMU_SETUP
- li t1, 0
- mtcr t1, t0
- ehb
-#endif
+ li t0, MMU_SETUP
+ li t1, 0
+ mtcr t1, t0
+ _ehb
-2: beqz v0, 4f
+2: beqz v0, 4f /* boot cpu (cpuid == 0)? */
nop
/* setup status reg */
- mfc0 t1, CP0_STATUS
- li t0, ST0_BEV
- or t1, t0
- xor t1, t0
+ move t1, zero
#ifdef CONFIG_64BIT
ori t1, ST0_KX
#endif
@@ -183,9 +224,9 @@ EXPORT(nlm_boot_siblings)
* For the boot CPU, we have to restore registers and
* return
*/
-4: dmfc0 t0, $4, 2 /* restore SP from UserLocal */
+4: dmfc0 t0, $4, 2 /* restore SP from UserLocal */
li t1, 0xfadebeef
- dmtc0 t1, $4, 2 /* restore SP from UserLocal */
+ dmtc0 t1, $4, 2 /* restore SP from UserLocal */
PTR_SUBU sp, t0, PT_SIZE
RESTORE_ALL
jr ra
@@ -193,7 +234,7 @@ EXPORT(nlm_boot_siblings)
EXPORT(nlm_reset_entry_end)
FEXPORT(xlp_boot_core0_siblings) /* "Master" cpu starts from here */
- __config_lsu
+ xlp_config_lsu
dmtc0 sp, $4, 2 /* SP saved in UserLocal */
SAVE_ALL
sync
@@ -210,6 +251,12 @@ FEXPORT(xlp_boot_core0_siblings) /* "Master" cpu starts from here */
__CPUINIT
NESTED(nlm_boot_secondary_cpus, 16, sp)
+ /* Initialize CP0 Status */
+ move t1, zero
+#ifdef CONFIG_64BIT
+ ori t1, ST0_KX
+#endif
+ mtc0 t1, CP0_STATUS
PTR_LA t1, nlm_next_sp
PTR_L sp, 0(t1)
PTR_LA t1, nlm_next_gp
@@ -234,36 +281,36 @@ END(nlm_boot_secondary_cpus)
*/
__CPUINIT
NESTED(nlm_rmiboot_preboot, 16, sp)
- mfc0 t0, $15, 1 # read ebase
- andi t0, 0x1f # t0 has the processor_id()
- andi t2, t0, 0x3 # thread no
- sll t0, 2 # offset in cpu array
+ mfc0 t0, $15, 1 /* read ebase */
+ andi t0, 0x1f /* t0 has the processor_id() */
+ andi t2, t0, 0x3 /* thread num */
+ sll t0, 2 /* offset in cpu array */
- PTR_LA t1, nlm_cpu_ready # mark CPU ready
+ PTR_LA t1, nlm_cpu_ready /* mark CPU ready */
PTR_ADDU t1, t0
li t3, 1
sw t3, 0(t1)
- bnez t2, 1f # skip thread programming
- nop # for non zero hw threads
+ bnez t2, 1f /* skip thread programming */
+ nop /* for thread id != 0 */
/*
- * MMU setup only for first thread in core
+ * XLR MMU setup only for first thread in core
*/
li t0, 0x400
mfcr t1, t0
- li t2, 6 # XLR thread mode mask
+ li t2, 6 /* XLR thread mode mask */
nor t3, t2, zero
- and t2, t1, t2 # t2 - current thread mode
+ and t2, t1, t2 /* t2 - current thread mode */
li v0, CKSEG1ADDR(RESET_DATA_PHYS)
- lw v1, BOOT_THREAD_MODE(v0) # v1 - new thread mode
+ lw v1, BOOT_THREAD_MODE(v0) /* v1 - new thread mode */
sll v1, 1
- beq v1, t2, 1f # same as request value
- nop # nothing to do */
+ beq v1, t2, 1f /* same as request value */
+ nop /* nothing to do */
- and t2, t1, t3 # mask out old thread mode
- or t1, t2, v1 # put in new value
- mtcr t1, t0 # update core control
+ and t2, t1, t3 /* mask out old thread mode */
+ or t1, t2, v1 /* put in new value */
+ mtcr t1, t0 /* update core control */
1: wait
j 1b
diff --git a/arch/mips/netlogic/xlp/Makefile b/arch/mips/netlogic/xlp/Makefile
index b93ed83474e..6b4b972218f 100644
--- a/arch/mips/netlogic/xlp/Makefile
+++ b/arch/mips/netlogic/xlp/Makefile
@@ -1,2 +1,4 @@
obj-y += setup.o platform.o nlm_hal.o
+obj-$(CONFIG_OF) += of.o
obj-$(CONFIG_SMP) += wakeup.o
+obj-$(CONFIG_USB) += usb-init.o
diff --git a/arch/mips/netlogic/xlp/nlm_hal.c b/arch/mips/netlogic/xlp/nlm_hal.c
index 9428e7125fe..6c65ac70191 100644
--- a/arch/mips/netlogic/xlp/nlm_hal.c
+++ b/arch/mips/netlogic/xlp/nlm_hal.c
@@ -69,6 +69,32 @@ int nlm_irq_to_irt(int irq)
return PIC_IRT_UART_0_INDEX;
case PIC_UART_1_IRQ:
return PIC_IRT_UART_1_INDEX;
+ case PIC_PCIE_LINK_0_IRQ:
+ return PIC_IRT_PCIE_LINK_0_INDEX;
+ case PIC_PCIE_LINK_1_IRQ:
+ return PIC_IRT_PCIE_LINK_1_INDEX;
+ case PIC_PCIE_LINK_2_IRQ:
+ return PIC_IRT_PCIE_LINK_2_INDEX;
+ case PIC_PCIE_LINK_3_IRQ:
+ return PIC_IRT_PCIE_LINK_3_INDEX;
+ case PIC_EHCI_0_IRQ:
+ return PIC_IRT_EHCI_0_INDEX;
+ case PIC_EHCI_1_IRQ:
+ return PIC_IRT_EHCI_1_INDEX;
+ case PIC_OHCI_0_IRQ:
+ return PIC_IRT_OHCI_0_INDEX;
+ case PIC_OHCI_1_IRQ:
+ return PIC_IRT_OHCI_1_INDEX;
+ case PIC_OHCI_2_IRQ:
+ return PIC_IRT_OHCI_2_INDEX;
+ case PIC_OHCI_3_IRQ:
+ return PIC_IRT_OHCI_3_INDEX;
+ case PIC_MMC_IRQ:
+ return PIC_IRT_MMC_INDEX;
+ case PIC_I2C_0_IRQ:
+ return PIC_IRT_I2C_0_INDEX;
+ case PIC_I2C_1_IRQ:
+ return PIC_IRT_I2C_1_INDEX;
default:
return -1;
}
@@ -81,6 +107,32 @@ int nlm_irt_to_irq(int irt)
return PIC_UART_0_IRQ;
case PIC_IRT_UART_1_INDEX:
return PIC_UART_1_IRQ;
+ case PIC_IRT_PCIE_LINK_0_INDEX:
+ return PIC_PCIE_LINK_0_IRQ;
+ case PIC_IRT_PCIE_LINK_1_INDEX:
+ return PIC_PCIE_LINK_1_IRQ;
+ case PIC_IRT_PCIE_LINK_2_INDEX:
+ return PIC_PCIE_LINK_2_IRQ;
+ case PIC_IRT_PCIE_LINK_3_INDEX:
+ return PIC_PCIE_LINK_3_IRQ;
+ case PIC_IRT_EHCI_0_INDEX:
+ return PIC_EHCI_0_IRQ;
+ case PIC_IRT_EHCI_1_INDEX:
+ return PIC_EHCI_1_IRQ;
+ case PIC_IRT_OHCI_0_INDEX:
+ return PIC_OHCI_0_IRQ;
+ case PIC_IRT_OHCI_1_INDEX:
+ return PIC_OHCI_1_IRQ;
+ case PIC_IRT_OHCI_2_INDEX:
+ return PIC_OHCI_2_IRQ;
+ case PIC_IRT_OHCI_3_INDEX:
+ return PIC_OHCI_3_IRQ;
+ case PIC_IRT_MMC_INDEX:
+ return PIC_MMC_IRQ;
+ case PIC_IRT_I2C_0_INDEX:
+ return PIC_I2C_0_IRQ;
+ case PIC_IRT_I2C_1_INDEX:
+ return PIC_I2C_1_IRQ;
default:
return -1;
}
diff --git a/arch/mips/netlogic/xlp/of.c b/arch/mips/netlogic/xlp/of.c
new file mode 100644
index 00000000000..8e3921c0c20
--- /dev/null
+++ b/arch/mips/netlogic/xlp/of.c
@@ -0,0 +1,34 @@
+#include <linux/bootmem.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/of_fdt.h>
+#include <asm/byteorder.h>
+
+static int __init reserve_mem_mach(unsigned long addr, unsigned long size)
+{
+ return reserve_bootmem(addr, size, BOOTMEM_DEFAULT);
+}
+
+void __init free_mem_mach(unsigned long addr, unsigned long size)
+{
+ return free_bootmem(addr, size);
+}
+
+void __init device_tree_init(void)
+{
+ unsigned long base, size;
+
+ if (!initial_boot_params)
+ return;
+
+ base = virt_to_phys((void *)initial_boot_params);
+ size = be32_to_cpu(initial_boot_params->totalsize);
+
+ /* Before we do anything, lets reserve the dt blob */
+ reserve_mem_mach(base, size);
+
+ unflatten_device_tree();
+
+ /* free the space reserved for the dt blob */
+ free_mem_mach(base, size);
+}
diff --git a/arch/mips/netlogic/xlp/platform.c b/arch/mips/netlogic/xlp/platform.c
index 1f5e4cba891..2c510d58544 100644
--- a/arch/mips/netlogic/xlp/platform.c
+++ b/arch/mips/netlogic/xlp/platform.c
@@ -53,7 +53,7 @@
static unsigned int nlm_xlp_uart_in(struct uart_port *p, int offset)
{
- return nlm_read_reg(p->iobase, offset);
+ return nlm_read_reg(p->iobase, offset);
}
static void nlm_xlp_uart_out(struct uart_port *p, int offset, int value)
diff --git a/arch/mips/netlogic/xlp/setup.c b/arch/mips/netlogic/xlp/setup.c
index b3df7c2aad1..3dec9f28b65 100644
--- a/arch/mips/netlogic/xlp/setup.c
+++ b/arch/mips/netlogic/xlp/setup.c
@@ -41,6 +41,8 @@
#include <asm/bootinfo.h>
#include <linux/of_fdt.h>
+#include <linux/of_platform.h>
+#include <linux/of_device.h>
#include <asm/netlogic/haldefs.h>
#include <asm/netlogic/common.h>
@@ -109,3 +111,17 @@ void __init prom_init(void)
register_smp_ops(&nlm_smp_ops);
#endif
}
+
+static struct of_device_id __initdata xlp_ids[] = {
+ { .compatible = "simple-bus", },
+ {},
+};
+
+int __init xlp8xx_ds_publish_devices(void)
+{
+ if (!of_have_populated_dt())
+ return 0;
+ return of_platform_bus_probe(NULL, xlp_ids, NULL);
+}
+
+device_initcall(xlp8xx_ds_publish_devices);
diff --git a/arch/mips/netlogic/xlp/usb-init.c b/arch/mips/netlogic/xlp/usb-init.c
new file mode 100644
index 00000000000..dbe083a9353
--- /dev/null
+++ b/arch/mips/netlogic/xlp/usb-init.c
@@ -0,0 +1,124 @@
+/*
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * All Rights Reserved
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the Broadcom
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BROADCOM ``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 BROADCOM OR CONTRIBUTORS 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.
+ */
+
+#include <linux/dma-mapping.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/platform_device.h>
+
+#include <asm/netlogic/haldefs.h>
+#include <asm/netlogic/xlp-hal/iomap.h>
+#include <asm/netlogic/xlp-hal/xlp.h>
+#include <asm/netlogic/xlp-hal/usb.h>
+
+static void nlm_usb_intr_en(int node, int port)
+{
+ uint32_t val;
+ uint64_t port_addr;
+
+ port_addr = nlm_get_usb_regbase(node, port);
+ val = nlm_read_usb_reg(port_addr, USB_INT_EN);
+ val = USB_CTRL_INTERRUPT_EN | USB_OHCI_INTERRUPT_EN |
+ USB_OHCI_INTERRUPT1_EN | USB_CTRL_INTERRUPT_EN |
+ USB_OHCI_INTERRUPT_EN | USB_OHCI_INTERRUPT2_EN;
+ nlm_write_usb_reg(port_addr, USB_INT_EN, val);
+}
+
+static void nlm_usb_hw_reset(int node, int port)
+{
+ uint64_t port_addr;
+ uint32_t val;
+
+ /* reset USB phy */
+ port_addr = nlm_get_usb_regbase(node, port);
+ val = nlm_read_usb_reg(port_addr, USB_PHY_0);
+ val &= ~(USB_PHY_RESET | USB_PHY_PORT_RESET_0 | USB_PHY_PORT_RESET_1);
+ nlm_write_usb_reg(port_addr, USB_PHY_0, val);
+
+ mdelay(100);
+ val = nlm_read_usb_reg(port_addr, USB_CTL_0);
+ val &= ~(USB_CONTROLLER_RESET);
+ val |= 0x4;
+ nlm_write_usb_reg(port_addr, USB_CTL_0, val);
+}
+
+static int __init nlm_platform_usb_init(void)
+{
+ pr_info("Initializing USB Interface\n");
+ nlm_usb_hw_reset(0, 0);
+ nlm_usb_hw_reset(0, 3);
+
+ /* Enable PHY interrupts */
+ nlm_usb_intr_en(0, 0);
+ nlm_usb_intr_en(0, 3);
+
+ return 0;
+}
+
+arch_initcall(nlm_platform_usb_init);
+
+static u64 xlp_usb_dmamask = ~(u32)0;
+
+/* Fixup the IRQ for USB devices which is exist on XLP SOC PCIE bus */
+static void nlm_usb_fixup_final(struct pci_dev *dev)
+{
+ dev->dev.dma_mask = &xlp_usb_dmamask;
+ dev->dev.coherent_dma_mask = DMA_BIT_MASK(64);
+ switch (dev->devfn) {
+ case 0x10:
+ dev->irq = PIC_EHCI_0_IRQ;
+ break;
+ case 0x11:
+ dev->irq = PIC_OHCI_0_IRQ;
+ break;
+ case 0x12:
+ dev->irq = PIC_OHCI_1_IRQ;
+ break;
+ case 0x13:
+ dev->irq = PIC_EHCI_1_IRQ;
+ break;
+ case 0x14:
+ dev->irq = PIC_OHCI_2_IRQ;
+ break;
+ case 0x15:
+ dev->irq = PIC_OHCI_3_IRQ;
+ break;
+ }
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_NETLOGIC, PCI_DEVICE_ID_NLM_EHCI,
+ nlm_usb_fixup_final);
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_NETLOGIC, PCI_DEVICE_ID_NLM_OHCI,
+ nlm_usb_fixup_final);
diff --git a/arch/mips/netlogic/xlr/Makefile b/arch/mips/netlogic/xlr/Makefile
index f01e4d7a060..c287dea8757 100644
--- a/arch/mips/netlogic/xlr/Makefile
+++ b/arch/mips/netlogic/xlr/Makefile
@@ -1,2 +1,2 @@
-obj-y += setup.o platform.o
+obj-y += setup.o platform.o platform-flash.o
obj-$(CONFIG_SMP) += wakeup.o
diff --git a/arch/mips/netlogic/xlr/platform-flash.c b/arch/mips/netlogic/xlr/platform-flash.c
new file mode 100644
index 00000000000..340ab1601c4
--- /dev/null
+++ b/arch/mips/netlogic/xlr/platform-flash.c
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2011, Netlogic Microsystems.
+ * Copyright 2004, Matt Porter <mporter@kernel.crashing.org>
+ *
+ * This file is licensed under the terms of the GNU General Public
+ * License version 2. This program is licensed "as is" without any
+ * warranty of any kind, whether express or implied.
+ */
+
+#include <linux/device.h>
+#include <linux/platform_device.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/resource.h>
+#include <linux/spi/flash.h>
+
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/physmap.h>
+#include <linux/mtd/nand.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/netlogic/haldefs.h>
+#include <asm/netlogic/xlr/iomap.h>
+#include <asm/netlogic/xlr/flash.h>
+#include <asm/netlogic/xlr/bridge.h>
+#include <asm/netlogic/xlr/gpio.h>
+#include <asm/netlogic/xlr/xlr.h>
+
+/*
+ * Default NOR partition layout
+ */
+static struct mtd_partition xlr_nor_parts[] = {
+ {
+ .name = "User FS",
+ .offset = 0x800000,
+ .size = MTDPART_SIZ_FULL,
+ }
+};
+
+/*
+ * Default NAND partition layout
+ */
+static struct mtd_partition xlr_nand_parts[] = {
+ {
+ .name = "Root Filesystem",
+ .offset = 64 * 64 * 2048,
+ .size = 432 * 64 * 2048,
+ },
+ {
+ .name = "Home Filesystem",
+ .offset = MTDPART_OFS_APPEND,
+ .size = MTDPART_SIZ_FULL,
+ },
+};
+
+/* Use PHYSMAP flash for NOR */
+struct physmap_flash_data xlr_nor_data = {
+ .width = 2,
+ .parts = xlr_nor_parts,
+ .nr_parts = ARRAY_SIZE(xlr_nor_parts),
+};
+
+static struct resource xlr_nor_res[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device xlr_nor_dev = {
+ .name = "physmap-flash",
+ .dev = {
+ .platform_data = &xlr_nor_data,
+ },
+ .num_resources = ARRAY_SIZE(xlr_nor_res),
+ .resource = xlr_nor_res,
+};
+
+const char *xlr_part_probes[] = { "cmdlinepart", NULL };
+
+/*
+ * Use "gen_nand" driver for NAND flash
+ *
+ * There seems to be no way to store a private pointer containing
+ * platform specific info in gen_nand drivier. We will use a global
+ * struct for now, since we currently have only one NAND chip per board.
+ */
+struct xlr_nand_flash_priv {
+ int cs;
+ uint64_t flash_mmio;
+};
+
+static struct xlr_nand_flash_priv nand_priv;
+
+static void xlr_nand_ctrl(struct mtd_info *mtd, int cmd,
+ unsigned int ctrl)
+{
+ if (ctrl & NAND_CLE)
+ nlm_write_reg(nand_priv.flash_mmio,
+ FLASH_NAND_CLE(nand_priv.cs), cmd);
+ else if (ctrl & NAND_ALE)
+ nlm_write_reg(nand_priv.flash_mmio,
+ FLASH_NAND_ALE(nand_priv.cs), cmd);
+}
+
+struct platform_nand_data xlr_nand_data = {
+ .chip = {
+ .nr_chips = 1,
+ .nr_partitions = ARRAY_SIZE(xlr_nand_parts),
+ .chip_delay = 50,
+ .partitions = xlr_nand_parts,
+ .part_probe_types = xlr_part_probes,
+ },
+ .ctrl = {
+ .cmd_ctrl = xlr_nand_ctrl,
+ },
+};
+
+static struct resource xlr_nand_res[] = {
+ {
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device xlr_nand_dev = {
+ .name = "gen_nand",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(xlr_nand_res),
+ .resource = xlr_nand_res,
+ .dev = {
+ .platform_data = &xlr_nand_data,
+ }
+};
+
+/*
+ * XLR/XLS supports upto 8 devices on its FLASH interface. The value in
+ * FLASH_BAR (on the MEM/IO bridge) gives the base for mapping all the
+ * flash devices.
+ * Under this, each flash device has an offset and size given by the
+ * CSBASE_ADDR and CSBASE_MASK registers for the device.
+ *
+ * The CSBASE_ registers are expected to be setup by the bootloader.
+ */
+static void setup_flash_resource(uint64_t flash_mmio,
+ uint64_t flash_map_base, int cs, struct resource *res)
+{
+ u32 base, mask;
+
+ base = nlm_read_reg(flash_mmio, FLASH_CSBASE_ADDR(cs));
+ mask = nlm_read_reg(flash_mmio, FLASH_CSADDR_MASK(cs));
+
+ res->start = flash_map_base + ((unsigned long)base << 16);
+ res->end = res->start + (mask + 1) * 64 * 1024;
+}
+
+static int __init xlr_flash_init(void)
+{
+ uint64_t gpio_mmio, flash_mmio, flash_map_base;
+ u32 gpio_resetcfg, flash_bar;
+ int cs, boot_nand, boot_nor;
+
+ /* Flash address bits 39:24 is in bridge flash BAR */
+ flash_bar = nlm_read_reg(nlm_io_base, BRIDGE_FLASH_BAR);
+ flash_map_base = (flash_bar & 0xffff0000) << 8;
+
+ gpio_mmio = nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET);
+ flash_mmio = nlm_mmio_base(NETLOGIC_IO_FLASH_OFFSET);
+
+ /* Get the chip reset config */
+ gpio_resetcfg = nlm_read_reg(gpio_mmio, GPIO_PWRON_RESET_CFG_REG);
+
+ /* Check for boot flash type */
+ boot_nor = boot_nand = 0;
+ if (nlm_chip_is_xls()) {
+ /* On XLS, check boot from NAND bit (GPIO reset reg bit 16) */
+ if (gpio_resetcfg & (1 << 16))
+ boot_nand = 1;
+
+ /* check boot from PCMCIA, (GPIO reset reg bit 15 */
+ if ((gpio_resetcfg & (1 << 15)) == 0)
+ boot_nor = 1; /* not set, booted from NOR */
+ } else { /* XLR */
+ /* check boot from PCMCIA (bit 16 in GPIO reset on XLR) */
+ if ((gpio_resetcfg & (1 << 16)) == 0)
+ boot_nor = 1; /* not set, booted from NOR */
+ }
+
+ /* boot flash at chip select 0 */
+ cs = 0;
+
+ if (boot_nand) {
+ nand_priv.cs = cs;
+ nand_priv.flash_mmio = flash_mmio;
+ setup_flash_resource(flash_mmio, flash_map_base, cs,
+ xlr_nand_res);
+
+ /* Initialize NAND flash at CS 0 */
+ nlm_write_reg(flash_mmio, FLASH_CSDEV_PARM(cs),
+ FLASH_NAND_CSDEV_PARAM);
+ nlm_write_reg(flash_mmio, FLASH_CSTIME_PARMA(cs),
+ FLASH_NAND_CSTIME_PARAMA);
+ nlm_write_reg(flash_mmio, FLASH_CSTIME_PARMB(cs),
+ FLASH_NAND_CSTIME_PARAMB);
+
+ pr_info("ChipSelect %d: NAND Flash %pR\n", cs, xlr_nand_res);
+ return platform_device_register(&xlr_nand_dev);
+ }
+
+ if (boot_nor) {
+ setup_flash_resource(flash_mmio, flash_map_base, cs,
+ xlr_nor_res);
+ pr_info("ChipSelect %d: NOR Flash %pR\n", cs, xlr_nor_res);
+ return platform_device_register(&xlr_nor_dev);
+ }
+ return 0;
+}
+
+arch_initcall(xlr_flash_init);
diff --git a/arch/mips/netlogic/xlr/platform.c b/arch/mips/netlogic/xlr/platform.c
index eab64b45dff..71b44d82621 100644
--- a/arch/mips/netlogic/xlr/platform.c
+++ b/arch/mips/netlogic/xlr/platform.c
@@ -14,6 +14,7 @@
#include <linux/resource.h>
#include <linux/serial_8250.h>
#include <linux/serial_reg.h>
+#include <linux/i2c.h>
#include <asm/netlogic/haldefs.h>
#include <asm/netlogic/xlr/iomap.h>
@@ -97,3 +98,142 @@ static int __init nlm_uart_init(void)
}
arch_initcall(nlm_uart_init);
+
+#ifdef CONFIG_USB
+/* Platform USB devices, only on XLS chips */
+static u64 xls_usb_dmamask = ~(u32)0;
+#define USB_PLATFORM_DEV(n, i, irq) \
+ { \
+ .name = n, \
+ .id = i, \
+ .num_resources = 2, \
+ .dev = { \
+ .dma_mask = &xls_usb_dmamask, \
+ .coherent_dma_mask = 0xffffffff, \
+ }, \
+ .resource = (struct resource[]) { \
+ { \
+ .flags = IORESOURCE_MEM, \
+ }, \
+ { \
+ .start = irq, \
+ .end = irq, \
+ .flags = IORESOURCE_IRQ, \
+ }, \
+ }, \
+ }
+
+static struct platform_device xls_usb_ehci_device =
+ USB_PLATFORM_DEV("ehci-xls", 0, PIC_USB_IRQ);
+static struct platform_device xls_usb_ohci_device_0 =
+ USB_PLATFORM_DEV("ohci-xls-0", 1, PIC_USB_IRQ);
+static struct platform_device xls_usb_ohci_device_1 =
+ USB_PLATFORM_DEV("ohci-xls-1", 2, PIC_USB_IRQ);
+
+static struct platform_device *xls_platform_devices[] = {
+ &xls_usb_ehci_device,
+ &xls_usb_ohci_device_0,
+ &xls_usb_ohci_device_1,
+};
+
+int xls_platform_usb_init(void)
+{
+ uint64_t usb_mmio, gpio_mmio;
+ unsigned long memres;
+ uint32_t val;
+
+ if (!nlm_chip_is_xls())
+ return 0;
+
+ gpio_mmio = nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET);
+ usb_mmio = nlm_mmio_base(NETLOGIC_IO_USB_1_OFFSET);
+
+ /* Clear Rogue Phy INTs */
+ nlm_write_reg(usb_mmio, 49, 0x10000000);
+ /* Enable all interrupts */
+ nlm_write_reg(usb_mmio, 50, 0x1f000000);
+
+ /* Enable ports */
+ nlm_write_reg(usb_mmio, 1, 0x07000500);
+
+ val = nlm_read_reg(gpio_mmio, 21);
+ if (((val >> 22) & 0x01) == 0) {
+ pr_info("Detected USB Device mode - Not supported!\n");
+ nlm_write_reg(usb_mmio, 0, 0x01000000);
+ return 0;
+ }
+
+ pr_info("Detected USB Host mode - Adding XLS USB devices.\n");
+ /* Clear reset, host mode */
+ nlm_write_reg(usb_mmio, 0, 0x02000000);
+
+ /* Memory resource for various XLS usb ports */
+ usb_mmio = nlm_mmio_base(NETLOGIC_IO_USB_0_OFFSET);
+ memres = CPHYSADDR((unsigned long)usb_mmio);
+ xls_usb_ehci_device.resource[0].start = memres;
+ xls_usb_ehci_device.resource[0].end = memres + 0x400 - 1;
+
+ memres += 0x400;
+ xls_usb_ohci_device_0.resource[0].start = memres;
+ xls_usb_ohci_device_0.resource[0].end = memres + 0x400 - 1;
+
+ memres += 0x400;
+ xls_usb_ohci_device_1.resource[0].start = memres;
+ xls_usb_ohci_device_1.resource[0].end = memres + 0x400 - 1;
+
+ return platform_add_devices(xls_platform_devices,
+ ARRAY_SIZE(xls_platform_devices));
+}
+
+arch_initcall(xls_platform_usb_init);
+#endif
+
+#ifdef CONFIG_I2C
+static struct i2c_board_info nlm_i2c_board_info1[] __initdata = {
+ /* All XLR boards have this RTC and Max6657 Temp Chip */
+ [0] = {
+ .type = "ds1374",
+ .addr = 0x68
+ },
+ [1] = {
+ .type = "lm90",
+ .addr = 0x4c
+ },
+};
+
+static struct resource i2c_resources[] = {
+ [0] = {
+ .start = 0, /* filled at init */
+ .end = 0,
+ .flags = IORESOURCE_MEM,
+ },
+};
+
+static struct platform_device nlm_xlr_i2c_1 = {
+ .name = "xlr-i2cbus",
+ .id = 1,
+ .num_resources = 1,
+ .resource = i2c_resources,
+};
+
+static int __init nlm_i2c_init(void)
+{
+ int err = 0;
+ unsigned int offset;
+
+ /* I2C bus 0 does not have any useful devices, configure only bus 1 */
+ offset = NETLOGIC_IO_I2C_1_OFFSET;
+ nlm_xlr_i2c_1.resource[0].start = CPHYSADDR(nlm_mmio_base(offset));
+ nlm_xlr_i2c_1.resource[0].end = nlm_xlr_i2c_1.resource[0].start + 0xfff;
+
+ platform_device_register(&nlm_xlr_i2c_1);
+
+ err = i2c_register_board_info(1, nlm_i2c_board_info1,
+ ARRAY_SIZE(nlm_i2c_board_info1));
+ if (err < 0)
+ pr_err("nlm-i2c: cannot register board I2C devices\n");
+ return err;
+}
+
+arch_initcall(nlm_i2c_init);
+#endif
diff --git a/arch/mips/netlogic/xlr/setup.c b/arch/mips/netlogic/xlr/setup.c
index c9d066dedc4..81b1d311834 100644
--- a/arch/mips/netlogic/xlr/setup.c
+++ b/arch/mips/netlogic/xlr/setup.c
@@ -85,7 +85,7 @@ static void nlm_linux_exit(void)
gpiobase = nlm_mmio_base(NETLOGIC_IO_GPIO_OFFSET);
/* trigger a chip reset by writing 1 to GPIO_SWRESET_REG */
- nlm_write_reg(gpiobase, NETLOGIC_GPIO_SWRESET_REG, 1);
+ nlm_write_reg(gpiobase, GPIO_SWRESET_REG, 1);
for ( ; ; )
cpu_wait();
}
diff --git a/arch/mips/oprofile/common.c b/arch/mips/oprofile/common.c
index b6e378211a2..f80480a5a03 100644
--- a/arch/mips/oprofile/common.c
+++ b/arch/mips/oprofile/common.c
@@ -85,6 +85,7 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
case CPU_34K:
case CPU_1004K:
case CPU_74K:
+ case CPU_LOONGSON1:
case CPU_SB1:
case CPU_SB1A:
case CPU_R10000:
diff --git a/arch/mips/oprofile/op_model_mipsxx.c b/arch/mips/oprofile/op_model_mipsxx.c
index 4d80a856048..28ea1a4cc57 100644
--- a/arch/mips/oprofile/op_model_mipsxx.c
+++ b/arch/mips/oprofile/op_model_mipsxx.c
@@ -339,12 +339,6 @@ static int __init mipsxx_init(void)
break;
case CPU_1004K:
-#if 0
- /* FIXME: report as 34K for now */
- op_model_mipsxx_ops.cpu_type = "mips/1004K";
- break;
-#endif
-
case CPU_34K:
op_model_mipsxx_ops.cpu_type = "mips/34K";
break;
@@ -374,6 +368,10 @@ static int __init mipsxx_init(void)
op_model_mipsxx_ops.cpu_type = "mips/sb1";
break;
+ case CPU_LOONGSON1:
+ op_model_mipsxx_ops.cpu_type = "mips/loongson1";
+ break;
+
default:
printk(KERN_ERR "Profiling unsupported for this CPU\n");
diff --git a/arch/mips/pci/Makefile b/arch/mips/pci/Makefile
index c703f43a991..e13a71cbc3c 100644
--- a/arch/mips/pci/Makefile
+++ b/arch/mips/pci/Makefile
@@ -59,6 +59,7 @@ obj-$(CONFIG_WR_PPMC) += fixup-wrppmc.o
obj-$(CONFIG_MIKROTIK_RB532) += pci-rc32434.o ops-rc32434.o fixup-rc32434.o
obj-$(CONFIG_CPU_CAVIUM_OCTEON) += pci-octeon.o pcie-octeon.o
obj-$(CONFIG_CPU_XLR) += pci-xlr.o
+obj-$(CONFIG_CPU_XLP) += pci-xlp.o
ifdef CONFIG_PCI_MSI
obj-$(CONFIG_CPU_CAVIUM_OCTEON) += msi-octeon.o
diff --git a/arch/mips/pci/fixup-cobalt.c b/arch/mips/pci/fixup-cobalt.c
index 9553b14002d..3e7ce65d776 100644
--- a/arch/mips/pci/fixup-cobalt.c
+++ b/arch/mips/pci/fixup-cobalt.c
@@ -37,7 +37,7 @@
#define VIA_COBALT_BRD_ID_REG 0x94
#define VIA_COBALT_BRD_REG_to_ID(reg) ((unsigned char)(reg) >> 4)
-static void qube_raq_galileo_early_fixup(struct pci_dev *dev)
+static void __devinit qube_raq_galileo_early_fixup(struct pci_dev *dev)
{
if (dev->devfn == PCI_DEVFN(0, 0) &&
(dev->class >> 8) == PCI_CLASS_MEMORY_OTHER) {
@@ -51,7 +51,7 @@ static void qube_raq_galileo_early_fixup(struct pci_dev *dev)
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111,
qube_raq_galileo_early_fixup);
-static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev)
+static void __devinit qube_raq_via_bmIDE_fixup(struct pci_dev *dev)
{
unsigned short cfgword;
unsigned char lt;
@@ -74,7 +74,7 @@ static void qube_raq_via_bmIDE_fixup(struct pci_dev *dev)
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_1,
qube_raq_via_bmIDE_fixup);
-static void qube_raq_galileo_fixup(struct pci_dev *dev)
+static void __devinit qube_raq_galileo_fixup(struct pci_dev *dev)
{
if (dev->devfn != PCI_DEVFN(0, 0))
return;
@@ -129,7 +129,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL, PCI_DEVICE_ID_MARVELL_GT64111,
int cobalt_board_id;
-static void qube_raq_via_board_id_fixup(struct pci_dev *dev)
+static void __devinit qube_raq_via_board_id_fixup(struct pci_dev *dev)
{
u8 id;
int retval;
diff --git a/arch/mips/pci/fixup-malta.c b/arch/mips/pci/fixup-malta.c
index 70073c98ed3..819622f93e9 100644
--- a/arch/mips/pci/fixup-malta.c
+++ b/arch/mips/pci/fixup-malta.c
@@ -101,3 +101,17 @@ static void __devinit malta_piix_func1_fixup(struct pci_dev *pdev)
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB,
malta_piix_func1_fixup);
+
+/* Enable PCI 2.1 compatibility in PIIX4 */
+static void __devinit quirk_dlcsetup(struct pci_dev *dev)
+{
+ u8 odlc, ndlc;
+
+ (void) pci_read_config_byte(dev, 0x82, &odlc);
+ /* Enable passive releases and delayed transaction */
+ ndlc = odlc | 7;
+ (void) pci_write_config_byte(dev, 0x82, ndlc);
+}
+
+DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_0,
+ quirk_dlcsetup);
diff --git a/arch/mips/pci/fixup-rc32434.c b/arch/mips/pci/fixup-rc32434.c
index 3d86823d03a..76bb1be99d4 100644
--- a/arch/mips/pci/fixup-rc32434.c
+++ b/arch/mips/pci/fixup-rc32434.c
@@ -47,7 +47,7 @@ int __devinit pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
return irq + GROUP4_IRQ_BASE + 4;
}
-static void rc32434_pci_early_fixup(struct pci_dev *dev)
+static void __devinit rc32434_pci_early_fixup(struct pci_dev *dev)
{
if (PCI_SLOT(dev->devfn) == 6 && dev->bus->number == 0) {
/* disable prefetched memory range */
diff --git a/arch/mips/pci/ops-bcm63xx.c b/arch/mips/pci/ops-bcm63xx.c
index 822ae179bc5..65c7bd10048 100644
--- a/arch/mips/pci/ops-bcm63xx.c
+++ b/arch/mips/pci/ops-bcm63xx.c
@@ -411,7 +411,7 @@ struct pci_ops bcm63xx_cb_ops = {
* only one IO window, so it cannot be shared by PCI and cardbus, use
* fixup to choose and detect unhandled configuration
*/
-static void bcm63xx_fixup(struct pci_dev *dev)
+static void __devinit bcm63xx_fixup(struct pci_dev *dev)
{
static int io_window = -1;
int i, found, new_io_window;
@@ -465,3 +465,64 @@ static void bcm63xx_fixup(struct pci_dev *dev)
DECLARE_PCI_FIXUP_ENABLE(PCI_ANY_ID, PCI_ANY_ID, bcm63xx_fixup);
#endif
+
+static int bcm63xx_pcie_can_access(struct pci_bus *bus, int devfn)
+{
+ switch (bus->number) {
+ case PCIE_BUS_BRIDGE:
+ return (PCI_SLOT(devfn) == 0);
+ case PCIE_BUS_DEVICE:
+ if (PCI_SLOT(devfn) == 0)
+ return bcm_pcie_readl(PCIE_DLSTATUS_REG)
+ & DLSTATUS_PHYLINKUP;
+ default:
+ return false;
+ }
+}
+
+static int bcm63xx_pcie_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ u32 data;
+ u32 reg = where & ~3;
+
+ if (!bcm63xx_pcie_can_access(bus, devfn))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if (bus->number == PCIE_BUS_DEVICE)
+ reg += PCIE_DEVICE_OFFSET;
+
+ data = bcm_pcie_readl(reg);
+
+ *val = postprocess_read(data, where, size);
+
+ return PCIBIOS_SUCCESSFUL;
+
+}
+
+static int bcm63xx_pcie_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 data;
+ u32 reg = where & ~3;
+
+ if (!bcm63xx_pcie_can_access(bus, devfn))
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if (bus->number == PCIE_BUS_DEVICE)
+ reg += PCIE_DEVICE_OFFSET;
+
+
+ data = bcm_pcie_readl(reg);
+
+ data = preprocess_write(data, val, where, size);
+ bcm_pcie_writel(data, reg);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+struct pci_ops bcm63xx_pcie_ops = {
+ .read = bcm63xx_pcie_read,
+ .write = bcm63xx_pcie_write
+};
diff --git a/arch/mips/pci/pci-bcm63xx.c b/arch/mips/pci/pci-bcm63xx.c
index 39eb7c417e2..8a48139d219 100644
--- a/arch/mips/pci/pci-bcm63xx.c
+++ b/arch/mips/pci/pci-bcm63xx.c
@@ -10,6 +10,7 @@
#include <linux/pci.h>
#include <linux/kernel.h>
#include <linux/init.h>
+#include <linux/delay.h>
#include <asm/bootinfo.h>
#include "pci-bcm63xx.h"
@@ -71,6 +72,26 @@ struct pci_controller bcm63xx_cb_controller = {
};
#endif
+static struct resource bcm_pcie_mem_resource = {
+ .name = "bcm63xx PCIe memory space",
+ .start = BCM_PCIE_MEM_BASE_PA,
+ .end = BCM_PCIE_MEM_END_PA,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource bcm_pcie_io_resource = {
+ .name = "bcm63xx PCIe IO space",
+ .start = 0,
+ .end = 0,
+ .flags = 0,
+};
+
+struct pci_controller bcm63xx_pcie_controller = {
+ .pci_ops = &bcm63xx_pcie_ops,
+ .io_resource = &bcm_pcie_io_resource,
+ .mem_resource = &bcm_pcie_mem_resource,
+};
+
static u32 bcm63xx_int_cfg_readl(u32 reg)
{
u32 tmp;
@@ -94,17 +115,99 @@ static void bcm63xx_int_cfg_writel(u32 val, u32 reg)
void __iomem *pci_iospace_start;
-static int __init bcm63xx_pci_init(void)
+static void __init bcm63xx_reset_pcie(void)
{
- unsigned int mem_size;
u32 val;
- if (!BCMCPU_IS_6348() && !BCMCPU_IS_6358() && !BCMCPU_IS_6368())
- return -ENODEV;
+ /* enable clock */
+ val = bcm_perf_readl(PERF_CKCTL_REG);
+ val |= CKCTL_6328_PCIE_EN;
+ bcm_perf_writel(val, PERF_CKCTL_REG);
+
+ /* enable SERDES */
+ val = bcm_misc_readl(MISC_SERDES_CTRL_REG);
+ val |= SERDES_PCIE_EN | SERDES_PCIE_EXD_EN;
+ bcm_misc_writel(val, MISC_SERDES_CTRL_REG);
+
+ /* reset the PCIe core */
+ val = bcm_perf_readl(PERF_SOFTRESET_6328_REG);
+
+ val &= ~SOFTRESET_6328_PCIE_MASK;
+ val &= ~SOFTRESET_6328_PCIE_CORE_MASK;
+ val &= ~SOFTRESET_6328_PCIE_HARD_MASK;
+ val &= ~SOFTRESET_6328_PCIE_EXT_MASK;
+ bcm_perf_writel(val, PERF_SOFTRESET_6328_REG);
+ mdelay(10);
+
+ val |= SOFTRESET_6328_PCIE_MASK;
+ val |= SOFTRESET_6328_PCIE_CORE_MASK;
+ val |= SOFTRESET_6328_PCIE_HARD_MASK;
+ bcm_perf_writel(val, PERF_SOFTRESET_6328_REG);
+ mdelay(10);
+
+ val |= SOFTRESET_6328_PCIE_EXT_MASK;
+ bcm_perf_writel(val, PERF_SOFTRESET_6328_REG);
+ mdelay(200);
+}
- if (!bcm63xx_pci_enabled)
- return -ENODEV;
+static int __init bcm63xx_register_pcie(void)
+{
+ u32 val;
+ bcm63xx_reset_pcie();
+
+ /* configure the PCIe bridge */
+ val = bcm_pcie_readl(PCIE_BRIDGE_OPT1_REG);
+ val |= OPT1_RD_BE_OPT_EN;
+ val |= OPT1_RD_REPLY_BE_FIX_EN;
+ val |= OPT1_PCIE_BRIDGE_HOLE_DET_EN;
+ val |= OPT1_L1_INT_STATUS_MASK_POL;
+ bcm_pcie_writel(val, PCIE_BRIDGE_OPT1_REG);
+
+ /* setup the interrupts */
+ val = bcm_pcie_readl(PCIE_BRIDGE_RC_INT_MASK_REG);
+ val |= PCIE_RC_INT_A | PCIE_RC_INT_B | PCIE_RC_INT_C | PCIE_RC_INT_D;
+ bcm_pcie_writel(val, PCIE_BRIDGE_RC_INT_MASK_REG);
+
+ val = bcm_pcie_readl(PCIE_BRIDGE_OPT2_REG);
+ /* enable credit checking and error checking */
+ val |= OPT2_TX_CREDIT_CHK_EN;
+ val |= OPT2_UBUS_UR_DECODE_DIS;
+
+ /* set device bus/func for the pcie device */
+ val |= (PCIE_BUS_DEVICE << OPT2_CFG_TYPE1_BUS_NO_SHIFT);
+ val |= OPT2_CFG_TYPE1_BD_SEL;
+ bcm_pcie_writel(val, PCIE_BRIDGE_OPT2_REG);
+
+ /* setup class code as bridge */
+ val = bcm_pcie_readl(PCIE_IDVAL3_REG);
+ val &= ~IDVAL3_CLASS_CODE_MASK;
+ val |= (PCI_CLASS_BRIDGE_PCI << IDVAL3_SUBCLASS_SHIFT);
+ bcm_pcie_writel(val, PCIE_IDVAL3_REG);
+
+ /* disable bar1 size */
+ val = bcm_pcie_readl(PCIE_CONFIG2_REG);
+ val &= ~CONFIG2_BAR1_SIZE_MASK;
+ bcm_pcie_writel(val, PCIE_CONFIG2_REG);
+
+ /* set bar0 to little endian */
+ val = (BCM_PCIE_MEM_BASE_PA >> 20) << BASEMASK_BASE_SHIFT;
+ val |= (BCM_PCIE_MEM_BASE_PA >> 20) << BASEMASK_MASK_SHIFT;
+ val |= BASEMASK_REMAP_EN;
+ bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_BASEMASK_REG);
+
+ val = (BCM_PCIE_MEM_BASE_PA >> 20) << REBASE_ADDR_BASE_SHIFT;
+ bcm_pcie_writel(val, PCIE_BRIDGE_BAR0_REBASE_ADDR_REG);
+
+ register_pci_controller(&bcm63xx_pcie_controller);
+
+ return 0;
+}
+
+static int __init bcm63xx_register_pci(void)
+{
+ unsigned int mem_size;
+ u32 val;
/*
* configuration access are done through IO space, remap 4
* first bytes to access it from CPU.
@@ -221,4 +324,22 @@ static int __init bcm63xx_pci_init(void)
return 0;
}
+
+static int __init bcm63xx_pci_init(void)
+{
+ if (!bcm63xx_pci_enabled)
+ return -ENODEV;
+
+ switch (bcm63xx_get_cpu_id()) {
+ case BCM6328_CPU_ID:
+ return bcm63xx_register_pcie();
+ case BCM6348_CPU_ID:
+ case BCM6358_CPU_ID:
+ case BCM6368_CPU_ID:
+ return bcm63xx_register_pci();
+ default:
+ return -ENODEV;
+ }
+}
+
arch_initcall(bcm63xx_pci_init);
diff --git a/arch/mips/pci/pci-bcm63xx.h b/arch/mips/pci/pci-bcm63xx.h
index a6e594ef3d6..e6736d558ac 100644
--- a/arch/mips/pci/pci-bcm63xx.h
+++ b/arch/mips/pci/pci-bcm63xx.h
@@ -13,11 +13,16 @@
*/
#define CARDBUS_PCI_IDSEL 0x8
+
+#define PCIE_BUS_BRIDGE 0
+#define PCIE_BUS_DEVICE 1
+
/*
* defined in ops-bcm63xx.c
*/
extern struct pci_ops bcm63xx_pci_ops;
extern struct pci_ops bcm63xx_cb_ops;
+extern struct pci_ops bcm63xx_pcie_ops;
/*
* defined in pci-bcm63xx.c
diff --git a/arch/mips/pci/pci-xlp.c b/arch/mips/pci/pci-xlp.c
new file mode 100644
index 00000000000..140557a2048
--- /dev/null
+++ b/arch/mips/pci/pci-xlp.c
@@ -0,0 +1,248 @@
+/*
+ * Copyright (c) 2003-2012 Broadcom Corporation
+ * All Rights Reserved
+ *
+ * This software is available to you under a choice of one of two
+ * licenses. You may choose to be licensed under the terms of the GNU
+ * General Public License (GPL) Version 2, available from the file
+ * COPYING in the main directory of this source tree, or the Broadcom
+ * license below:
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY BROADCOM ``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 BROADCOM OR CONTRIBUTORS 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.
+ */
+
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/msi.h>
+#include <linux/mm.h>
+#include <linux/irq.h>
+#include <linux/irqdesc.h>
+#include <linux/console.h>
+
+#include <asm/io.h>
+
+#include <asm/netlogic/interrupt.h>
+#include <asm/netlogic/haldefs.h>
+
+#include <asm/netlogic/xlp-hal/iomap.h>
+#include <asm/netlogic/xlp-hal/pic.h>
+#include <asm/netlogic/xlp-hal/xlp.h>
+#include <asm/netlogic/xlp-hal/pcibus.h>
+#include <asm/netlogic/xlp-hal/bridge.h>
+
+static void *pci_config_base;
+
+#define pci_cfg_addr(bus, devfn, off) (((bus) << 20) | ((devfn) << 12) | (off))
+
+/* PCI ops */
+static inline u32 pci_cfg_read_32bit(struct pci_bus *bus, unsigned int devfn,
+ int where)
+{
+ u32 data;
+ u32 *cfgaddr;
+
+ cfgaddr = (u32 *)(pci_config_base +
+ pci_cfg_addr(bus->number, devfn, where & ~3));
+ data = *cfgaddr;
+ return data;
+}
+
+static inline void pci_cfg_write_32bit(struct pci_bus *bus, unsigned int devfn,
+ int where, u32 data)
+{
+ u32 *cfgaddr;
+
+ cfgaddr = (u32 *)(pci_config_base +
+ pci_cfg_addr(bus->number, devfn, where & ~3));
+ *cfgaddr = data;
+}
+
+static int nlm_pcibios_read(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 *val)
+{
+ u32 data;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ data = pci_cfg_read_32bit(bus, devfn, where);
+
+ if (size == 1)
+ *val = (data >> ((where & 3) << 3)) & 0xff;
+ else if (size == 2)
+ *val = (data >> ((where & 3) << 3)) & 0xffff;
+ else
+ *val = data;
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+
+static int nlm_pcibios_write(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, u32 val)
+{
+ u32 data;
+
+ if ((size == 2) && (where & 1))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+ else if ((size == 4) && (where & 3))
+ return PCIBIOS_BAD_REGISTER_NUMBER;
+
+ data = pci_cfg_read_32bit(bus, devfn, where);
+
+ if (size == 1)
+ data = (data & ~(0xff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else if (size == 2)
+ data = (data & ~(0xffff << ((where & 3) << 3))) |
+ (val << ((where & 3) << 3));
+ else
+ data = val;
+
+ pci_cfg_write_32bit(bus, devfn, where, data);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops nlm_pci_ops = {
+ .read = nlm_pcibios_read,
+ .write = nlm_pcibios_write
+};
+
+static struct resource nlm_pci_mem_resource = {
+ .name = "XLP PCI MEM",
+ .start = 0xd0000000UL, /* 256MB PCI mem @ 0xd000_0000 */
+ .end = 0xdfffffffUL,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct resource nlm_pci_io_resource = {
+ .name = "XLP IO MEM",
+ .start = 0x14000000UL, /* 64MB PCI IO @ 0x1000_0000 */
+ .end = 0x17ffffffUL,
+ .flags = IORESOURCE_IO,
+};
+
+struct pci_controller nlm_pci_controller = {
+ .index = 0,
+ .pci_ops = &nlm_pci_ops,
+ .mem_resource = &nlm_pci_mem_resource,
+ .mem_offset = 0x00000000UL,
+ .io_resource = &nlm_pci_io_resource,
+ .io_offset = 0x00000000UL,
+};
+
+static int get_irq_vector(const struct pci_dev *dev)
+{
+ /*
+ * For XLP PCIe, there is an IRQ per Link, find out which
+ * link the device is on to assign interrupts
+ */
+ if (dev->bus->self == NULL)
+ return 0;
+
+ switch (dev->bus->self->devfn) {
+ case 0x8:
+ return PIC_PCIE_LINK_0_IRQ;
+ case 0x9:
+ return PIC_PCIE_LINK_1_IRQ;
+ case 0xa:
+ return PIC_PCIE_LINK_2_IRQ;
+ case 0xb:
+ return PIC_PCIE_LINK_3_IRQ;
+ }
+ WARN(1, "Unexpected devfn %d\n", dev->bus->self->devfn);
+ return 0;
+}
+
+int __init pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+{
+ return get_irq_vector(dev);
+}
+
+/* Do platform specific device initialization at pci_enable_device() time */
+int pcibios_plat_dev_init(struct pci_dev *dev)
+{
+ return 0;
+}
+
+static int xlp_enable_pci_bswap(void)
+{
+ uint64_t pciebase, sysbase;
+ int node, i;
+ u32 reg;
+
+ /* Chip-0 so node set to 0 */
+ node = 0;
+ sysbase = nlm_get_bridge_regbase(node);
+ /*
+ * Enable byte swap in hardware. Program each link's PCIe SWAP regions
+ * from the link's address ranges.
+ */
+ for (i = 0; i < 4; i++) {
+ pciebase = nlm_pcicfg_base(XLP_IO_PCIE_OFFSET(node, i));
+ if (nlm_read_pci_reg(pciebase, 0) == 0xffffffff)
+ continue;
+
+ reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEMEM_BASE0 + i);
+ nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_MEM_BASE, reg);
+
+ reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEMEM_LIMIT0 + i);
+ nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_MEM_LIM,
+ reg | 0xfff);
+
+ reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_BASE0 + i);
+ nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_BASE, reg);
+
+ reg = nlm_read_bridge_reg(sysbase, BRIDGE_PCIEIO_LIMIT0 + i);
+ nlm_write_pci_reg(pciebase, PCIE_BYTE_SWAP_IO_LIM, reg | 0xfff);
+ }
+ return 0;
+}
+
+static int __init pcibios_init(void)
+{
+ /* Firmware assigns PCI resources */
+ pci_set_flags(PCI_PROBE_ONLY);
+ pci_config_base = ioremap(XLP_DEFAULT_PCI_ECFG_BASE, 64 << 20);
+
+ /* Extend IO port for memory mapped io */
+ ioport_resource.start = 0;
+ ioport_resource.end = ~0;
+
+ xlp_enable_pci_bswap();
+ set_io_port_base(CKSEG1);
+ nlm_pci_controller.io_map_base = CKSEG1;
+
+ register_pci_controller(&nlm_pci_controller);
+ pr_info("XLP PCIe Controller %pR%pR.\n", &nlm_pci_io_resource,
+ &nlm_pci_mem_resource);
+
+ return 0;
+}
+arch_initcall(pcibios_init);
diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c
index 172af1cd586..18af021d289 100644
--- a/arch/mips/pci/pci-xlr.c
+++ b/arch/mips/pci/pci-xlr.c
@@ -375,7 +375,3 @@ static int __init pcibios_init(void)
}
arch_initcall(pcibios_init);
-
-struct pci_fixup pcibios_fixups[] = {
- {0}
-};
diff --git a/arch/mips/pnx833x/stb22x/board.c b/arch/mips/pnx833x/stb22x/board.c
index 644eb7c3210..4b328ac4305 100644
--- a/arch/mips/pnx833x/stb22x/board.c
+++ b/arch/mips/pnx833x/stb22x/board.c
@@ -91,7 +91,7 @@ void __init pnx833x_board_setup(void)
pnx833x_gpio_select_function_alt(32);
pnx833x_gpio_select_function_alt(33);
-#if defined(CONFIG_MTD_NAND_PLATFORM) || defined(CONFIG_MTD_NAND_PLATFORM_MODULE)
+#if IS_ENABLED(CONFIG_MTD_NAND_PLATFORM)
/* Setup MIU for NAND access on CS0...
*
* (it seems that we must also configure CS1 for reliable operation,
@@ -117,7 +117,7 @@ void __init pnx833x_board_setup(void)
pnx833x_gpio_select_output(5);
pnx833x_gpio_write(1, 5);
-#elif defined(CONFIG_MTD_CFI) || defined(CONFIG_MTD_CFI_MODULE)
+#elif IS_ENABLED(CONFIG_MTD_CFI)
/* Set up MIU for 16-bit NOR access on CS0 and CS1... */
diff --git a/arch/mips/sgi-ip27/ip27-memory.c b/arch/mips/sgi-ip27/ip27-memory.c
index b105eca3c02..cd8fcab6b05 100644
--- a/arch/mips/sgi-ip27/ip27-memory.c
+++ b/arch/mips/sgi-ip27/ip27-memory.c
@@ -401,6 +401,7 @@ static void __init node_mem_init(cnodeid_t node)
* Allocate the node data structures on the node first.
*/
__node_data[node] = __va(slot_freepfn << PAGE_SHIFT);
+ memset(__node_data[node], 0, PAGE_SIZE);
NODE_DATA(node)->bdata = &bootmem_node_data[node];
NODE_DATA(node)->node_start_pfn = start_pfn;
diff --git a/arch/mips/txx9/Kconfig b/arch/mips/txx9/Kconfig
index 852ae4bb7a8..6d40bc78345 100644
--- a/arch/mips/txx9/Kconfig
+++ b/arch/mips/txx9/Kconfig
@@ -20,6 +20,7 @@ config MACH_TXX9
select SYS_SUPPORTS_32BIT_KERNEL
select SYS_SUPPORTS_LITTLE_ENDIAN
select SYS_SUPPORTS_BIG_ENDIAN
+ select HAVE_CLK
config TOSHIBA_JMR3927
bool "Toshiba JMR-TX3927 board"
diff --git a/arch/mips/txx9/generic/pci.c b/arch/mips/txx9/generic/pci.c
index 125db323ab1..4efd9185f29 100644
--- a/arch/mips/txx9/generic/pci.c
+++ b/arch/mips/txx9/generic/pci.c
@@ -304,7 +304,7 @@ static void __devinit quirk_slc90e66_bridge(struct pci_dev *dev)
smsc_fdc37m81x_config_end();
}
-static void quirk_slc90e66_ide(struct pci_dev *dev)
+static void __devinit quirk_slc90e66_ide(struct pci_dev *dev)
{
unsigned char dat;
int regs[2] = {0x41, 0x43};
@@ -339,7 +339,7 @@ static void quirk_slc90e66_ide(struct pci_dev *dev)
}
#endif /* CONFIG_TOSHIBA_FPCIB0 */
-static void tc35815_fixup(struct pci_dev *dev)
+static void __devinit tc35815_fixup(struct pci_dev *dev)
{
/* This device may have PM registers but not they are not suported. */
if (dev->pm_cap) {
@@ -348,7 +348,7 @@ static void tc35815_fixup(struct pci_dev *dev)
}
}
-static void final_fixup(struct pci_dev *dev)
+static void __devinit final_fixup(struct pci_dev *dev)
{
unsigned char bist;
diff --git a/arch/mips/txx9/generic/setup.c b/arch/mips/txx9/generic/setup.c
index ae77a7916c0..560fe899175 100644
--- a/arch/mips/txx9/generic/setup.c
+++ b/arch/mips/txx9/generic/setup.c
@@ -632,7 +632,7 @@ void __init txx9_physmap_flash_init(int no, unsigned long addr,
unsigned long size,
const struct physmap_flash_data *pdata)
{
-#if defined(CONFIG_MTD_PHYSMAP) || defined(CONFIG_MTD_PHYSMAP_MODULE)
+#if IS_ENABLED(CONFIG_MTD_PHYSMAP)
struct resource res = {
.start = addr,
.end = addr + size - 1,
@@ -670,8 +670,7 @@ void __init txx9_physmap_flash_init(int no, unsigned long addr,
void __init txx9_ndfmc_init(unsigned long baseaddr,
const struct txx9ndfmc_platform_data *pdata)
{
-#if defined(CONFIG_MTD_NAND_TXX9NDFMC) || \
- defined(CONFIG_MTD_NAND_TXX9NDFMC_MODULE)
+#if IS_ENABLED(CONFIG_MTD_NAND_TXX9NDFMC)
struct resource res = {
.start = baseaddr,
.end = baseaddr + 0x1000 - 1,
@@ -687,7 +686,7 @@ void __init txx9_ndfmc_init(unsigned long baseaddr,
#endif
}
-#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
+#if IS_ENABLED(CONFIG_LEDS_GPIO)
static DEFINE_SPINLOCK(txx9_iocled_lock);
#define TXX9_IOCLED_MAXLEDS 8
@@ -810,7 +809,7 @@ void __init txx9_iocled_init(unsigned long baseaddr,
void __init txx9_dmac_init(int id, unsigned long baseaddr, int irq,
const struct txx9dmac_platform_data *pdata)
{
-#if defined(CONFIG_TXX9_DMAC) || defined(CONFIG_TXX9_DMAC_MODULE)
+#if IS_ENABLED(CONFIG_TXX9_DMAC)
struct resource res[] = {
{
.start = baseaddr,
@@ -866,8 +865,7 @@ void __init txx9_aclc_init(unsigned long baseaddr, int irq,
unsigned int dma_chan_out,
unsigned int dma_chan_in)
{
-#if defined(CONFIG_SND_SOC_TXX9ACLC) || \
- defined(CONFIG_SND_SOC_TXX9ACLC_MODULE)
+#if IS_ENABLED(CONFIG_SND_SOC_TXX9ACLC)
unsigned int dma_base = dmac_id * TXX9_DMA_MAX_NR_CHANNELS;
struct resource res[] = {
{
diff --git a/arch/mips/txx9/generic/setup_tx4939.c b/arch/mips/txx9/generic/setup_tx4939.c
index 6567895d1f5..5ff7a9584da 100644
--- a/arch/mips/txx9/generic/setup_tx4939.c
+++ b/arch/mips/txx9/generic/setup_tx4939.c
@@ -317,7 +317,7 @@ void __init tx4939_sio_init(unsigned int sclk, unsigned int cts_mask)
}
}
-#if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE)
+#if IS_ENABLED(CONFIG_TC35815)
static u32 tx4939_get_eth_speed(struct net_device *dev)
{
struct ethtool_cmd cmd;
diff --git a/arch/mips/txx9/rbtx4939/setup.c b/arch/mips/txx9/rbtx4939/setup.c
index 2ad8973ba13..e15641d9309 100644
--- a/arch/mips/txx9/rbtx4939/setup.c
+++ b/arch/mips/txx9/rbtx4939/setup.c
@@ -40,8 +40,7 @@ static void __init rbtx4939_time_init(void)
tx4939_time_init(0);
}
-#if defined(__BIG_ENDIAN) && \
- (defined(CONFIG_SMC91X) || defined(CONFIG_SMC91X_MODULE))
+#if defined(__BIG_ENDIAN) && IS_ENABLED(CONFIG_SMC91X)
#define HAVE_RBTX4939_IOSWAB
#define IS_CE1_ADDR(addr) \
((((unsigned long)(addr) - IO_BASE) & 0xfff00000) == TXX9_CE(1))
@@ -187,7 +186,7 @@ static void __init rbtx4939_update_ioc_pen(void)
#define RBTX4939_MAX_7SEGLEDS 8
-#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
+#if IS_ENABLED(CONFIG_LEDS_CLASS)
static u8 led_val[RBTX4939_MAX_7SEGLEDS];
struct rbtx4939_led_data {
struct led_classdev cdev;
@@ -263,7 +262,7 @@ static inline void rbtx4939_led_setup(void)
static void __rbtx4939_7segled_putc(unsigned int pos, unsigned char val)
{
-#if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE)
+#if IS_ENABLED(CONFIG_LEDS_CLASS)
unsigned long flags;
local_irq_save(flags);
/* bit7: reserved for LED class */
@@ -287,7 +286,7 @@ static void rbtx4939_7segled_putc(unsigned int pos, unsigned char val)
__rbtx4939_7segled_putc(pos, val);
}
-#if defined(CONFIG_MTD_RBTX4939) || defined(CONFIG_MTD_RBTX4939_MODULE)
+#if IS_ENABLED(CONFIG_MTD_RBTX4939)
/* special mapping for boot rom */
static unsigned long rbtx4939_flash_fixup_ofs(unsigned long ofs)
{
@@ -463,7 +462,7 @@ static void __init rbtx4939_device_init(void)
.flags = SMC91X_USE_16BIT,
};
struct platform_device *pdev;
-#if defined(CONFIG_TC35815) || defined(CONFIG_TC35815_MODULE)
+#if IS_ENABLED(CONFIG_TC35815)
int i, j;
unsigned char ethaddr[2][6];
u8 bdipsw = readb(rbtx4939_bdipsw_addr) & 0x0f;
diff --git a/arch/mn10300/Kconfig b/arch/mn10300/Kconfig
index 687f9b4a2ed..5cfb086b390 100644
--- a/arch/mn10300/Kconfig
+++ b/arch/mn10300/Kconfig
@@ -3,6 +3,7 @@ config MN10300
select HAVE_OPROFILE
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_SHOW
+ select ARCH_WANT_IPC_PARSE_VERSION
select HAVE_ARCH_TRACEHOOK
select HAVE_ARCH_KGDB
select HAVE_NMI_WATCHDOG if MN10300_WD_TIMER
diff --git a/arch/mn10300/include/asm/ipc.h b/arch/mn10300/include/asm/ipc.h
deleted file mode 100644
index a46e3d9c2a3..00000000000
--- a/arch/mn10300/include/asm/ipc.h
+++ /dev/null
@@ -1 +0,0 @@
-#include <asm-generic/ipc.h>
diff --git a/arch/mn10300/include/asm/unistd.h b/arch/mn10300/include/asm/unistd.h
index 9051f921cbc..866eb14749d 100644
--- a/arch/mn10300/include/asm/unistd.h
+++ b/arch/mn10300/include/asm/unistd.h
@@ -358,7 +358,6 @@
/*
* specify the deprecated syscalls we want to support on this arch
*/
-#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_OLD_STAT
#define __ARCH_WANT_STAT64
diff --git a/arch/openrisc/include/asm/Kbuild b/arch/openrisc/include/asm/Kbuild
index 3f35c38d7b6..0922959663a 100644
--- a/arch/openrisc/include/asm/Kbuild
+++ b/arch/openrisc/include/asm/Kbuild
@@ -13,7 +13,6 @@ generic-y += cacheflush.h
generic-y += checksum.h
generic-y += cmpxchg.h
generic-y += cmpxchg-local.h
-generic-y += cpumask.h
generic-y += cputime.h
generic-y += current.h
generic-y += device.h
@@ -43,7 +42,6 @@ generic-y += percpu.h
generic-y += poll.h
generic-y += posix_types.h
generic-y += resource.h
-generic-y += rmap.h
generic-y += scatterlist.h
generic-y += sections.h
generic-y += segment.h
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 9a5d3cdc3e1..352f416269c 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -115,11 +115,13 @@ config PPC
select HAVE_OPROFILE
select HAVE_SYSCALL_WRAPPERS if PPC64
select GENERIC_ATOMIC64 if PPC32
+ select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select HAVE_IRQ_WORK
select HAVE_PERF_EVENTS
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_HW_BREAKPOINT if PERF_EVENTS && PPC_BOOK3S_64
select HAVE_GENERIC_HARDIRQS
+ select ARCH_WANT_IPC_PARSE_VERSION
select SPARSE_IRQ
select IRQ_PER_CPU
select IRQ_DOMAIN
diff --git a/arch/powerpc/boot/dts/p2020rdb-pc_32b.dts b/arch/powerpc/boot/dts/p2020rdb-pc_32b.dts
index 852e5b27485..57573bd52ca 100644
--- a/arch/powerpc/boot/dts/p2020rdb-pc_32b.dts
+++ b/arch/powerpc/boot/dts/p2020rdb-pc_32b.dts
@@ -56,7 +56,7 @@
ranges = <0x0 0x0 0xffe00000 0x100000>;
};
- pci0: pcie@ffe08000 {
+ pci2: pcie@ffe08000 {
reg = <0 0xffe08000 0 0x1000>;
status = "disabled";
};
@@ -76,7 +76,7 @@
};
};
- pci2: pcie@ffe0a000 {
+ pci0: pcie@ffe0a000 {
reg = <0 0xffe0a000 0 0x1000>;
ranges = <0x2000000 0x0 0xe0000000 0 0x80000000 0x0 0x20000000
0x1000000 0x0 0x00000000 0 0xffc00000 0x0 0x10000>;
diff --git a/arch/powerpc/boot/dts/p2020rdb-pc_36b.dts b/arch/powerpc/boot/dts/p2020rdb-pc_36b.dts
index b5a56ca51cf..470247ea68b 100644
--- a/arch/powerpc/boot/dts/p2020rdb-pc_36b.dts
+++ b/arch/powerpc/boot/dts/p2020rdb-pc_36b.dts
@@ -56,7 +56,7 @@
ranges = <0x0 0xf 0xffe00000 0x100000>;
};
- pci0: pcie@fffe08000 {
+ pci2: pcie@fffe08000 {
reg = <0xf 0xffe08000 0 0x1000>;
status = "disabled";
};
@@ -76,7 +76,7 @@
};
};
- pci2: pcie@fffe0a000 {
+ pci0: pcie@fffe0a000 {
reg = <0xf 0xffe0a000 0 0x1000>;
ranges = <0x2000000 0x0 0xe0000000 0xc 0x00000000 0x0 0x20000000
0x1000000 0x0 0x00000000 0xf 0xffc00000 0x0 0x10000>;
diff --git a/arch/powerpc/boot/dts/p3041ds.dts b/arch/powerpc/boot/dts/p3041ds.dts
index 22a215e9416..6cdcadc80c3 100644
--- a/arch/powerpc/boot/dts/p3041ds.dts
+++ b/arch/powerpc/boot/dts/p3041ds.dts
@@ -58,7 +58,7 @@
#size-cells = <1>;
compatible = "spansion,s25sl12801";
reg = <0>;
- spi-max-frequency = <40000000>; /* input clock */
+ spi-max-frequency = <35000000>; /* input clock */
partition@u-boot {
label = "u-boot";
reg = <0x00000000 0x00100000>;
diff --git a/arch/powerpc/configs/chroma_defconfig b/arch/powerpc/configs/chroma_defconfig
index b1f9597fe31..29bb11ec6c6 100644
--- a/arch/powerpc/configs/chroma_defconfig
+++ b/arch/powerpc/configs/chroma_defconfig
@@ -21,8 +21,8 @@ CONFIG_CGROUP_DEVICE=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
-CONFIG_CGROUP_MEM_RES_CTLR=y
-CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
+CONFIG_CGROUP_MEMCG=y
+CONFIG_CGROUP_MEMCG_SWAP=y
CONFIG_NAMESPACES=y
CONFIG_RELAY=y
CONFIG_BLK_DEV_INITRD=y
diff --git a/arch/powerpc/include/asm/dma-mapping.h b/arch/powerpc/include/asm/dma-mapping.h
index 62678e365ca..78160874809 100644
--- a/arch/powerpc/include/asm/dma-mapping.h
+++ b/arch/powerpc/include/asm/dma-mapping.h
@@ -27,7 +27,10 @@ extern void *dma_direct_alloc_coherent(struct device *dev, size_t size,
extern void dma_direct_free_coherent(struct device *dev, size_t size,
void *vaddr, dma_addr_t dma_handle,
struct dma_attrs *attrs);
-
+extern int dma_direct_mmap_coherent(struct device *dev,
+ struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle,
+ size_t size, struct dma_attrs *attrs);
#ifdef CONFIG_NOT_COHERENT_CACHE
/*
@@ -207,11 +210,8 @@ static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
-extern int dma_mmap_coherent(struct device *, struct vm_area_struct *,
- void *, dma_addr_t, size_t);
#define ARCH_HAS_DMA_MMAP_COHERENT
-
static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction)
{
diff --git a/arch/powerpc/include/asm/unistd.h b/arch/powerpc/include/asm/unistd.h
index d3d1b5efd7e..bd377a36861 100644
--- a/arch/powerpc/include/asm/unistd.h
+++ b/arch/powerpc/include/asm/unistd.h
@@ -389,7 +389,6 @@
#include <linux/compiler.h>
#include <linux/linkage.h>
-#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c
index bcfdcd22c76..2d7bb8ced13 100644
--- a/arch/powerpc/kernel/dma-iommu.c
+++ b/arch/powerpc/kernel/dma-iommu.c
@@ -109,6 +109,7 @@ static u64 dma_iommu_get_required_mask(struct device *dev)
struct dma_map_ops dma_iommu_ops = {
.alloc = dma_iommu_alloc_coherent,
.free = dma_iommu_free_coherent,
+ .mmap = dma_direct_mmap_coherent,
.map_sg = dma_iommu_map_sg,
.unmap_sg = dma_iommu_unmap_sg,
.dma_supported = dma_iommu_dma_supported,
diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/dma-swiotlb.c
index 4ab88dafb23..46943651da2 100644
--- a/arch/powerpc/kernel/dma-swiotlb.c
+++ b/arch/powerpc/kernel/dma-swiotlb.c
@@ -49,6 +49,7 @@ static u64 swiotlb_powerpc_get_required(struct device *dev)
struct dma_map_ops swiotlb_dma_ops = {
.alloc = dma_direct_alloc_coherent,
.free = dma_direct_free_coherent,
+ .mmap = dma_direct_mmap_coherent,
.map_sg = swiotlb_map_sg_attrs,
.unmap_sg = swiotlb_unmap_sg_attrs,
.dma_supported = swiotlb_dma_supported,
diff --git a/arch/powerpc/kernel/dma.c b/arch/powerpc/kernel/dma.c
index 289be751cd7..355b9d84b0f 100644
--- a/arch/powerpc/kernel/dma.c
+++ b/arch/powerpc/kernel/dma.c
@@ -67,6 +67,24 @@ void dma_direct_free_coherent(struct device *dev, size_t size,
#endif
}
+int dma_direct_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
+ void *cpu_addr, dma_addr_t handle, size_t size,
+ struct dma_attrs *attrs)
+{
+ unsigned long pfn;
+
+#ifdef CONFIG_NOT_COHERENT_CACHE
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+ pfn = __dma_get_coherent_pfn((unsigned long)cpu_addr);
+#else
+ pfn = page_to_pfn(virt_to_page(cpu_addr));
+#endif
+ return remap_pfn_range(vma, vma->vm_start,
+ pfn + vma->vm_pgoff,
+ vma->vm_end - vma->vm_start,
+ vma->vm_page_prot);
+}
+
static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
int nents, enum dma_data_direction direction,
struct dma_attrs *attrs)
@@ -156,6 +174,7 @@ static inline void dma_direct_sync_single(struct device *dev,
struct dma_map_ops dma_direct_ops = {
.alloc = dma_direct_alloc_coherent,
.free = dma_direct_free_coherent,
+ .mmap = dma_direct_mmap_coherent,
.map_sg = dma_direct_map_sg,
.unmap_sg = dma_direct_unmap_sg,
.dma_supported = dma_direct_dma_supported,
@@ -219,20 +238,3 @@ static int __init dma_init(void)
}
fs_initcall(dma_init);
-int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma,
- void *cpu_addr, dma_addr_t handle, size_t size)
-{
- unsigned long pfn;
-
-#ifdef CONFIG_NOT_COHERENT_CACHE
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
- pfn = __dma_get_coherent_pfn((unsigned long)cpu_addr);
-#else
- pfn = page_to_pfn(virt_to_page(cpu_addr));
-#endif
- return remap_pfn_range(vma, vma->vm_start,
- pfn + vma->vm_pgoff,
- vma->vm_end - vma->vm_start,
- vma->vm_page_prot);
-}
-EXPORT_SYMBOL_GPL(dma_mmap_coherent);
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index 3052a931f2b..02b32216bbc 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -611,6 +611,7 @@ static u64 vio_dma_get_required_mask(struct device *dev)
struct dma_map_ops vio_dma_mapping_ops = {
.alloc = vio_dma_iommu_alloc_coherent,
.free = vio_dma_iommu_free_coherent,
+ .mmap = dma_direct_mmap_coherent,
.map_sg = vio_dma_iommu_map_sg,
.unmap_sg = vio_dma_iommu_unmap_sg,
.map_page = vio_dma_iommu_map_page,
diff --git a/arch/powerpc/kvm/book3s_rmhandlers.S b/arch/powerpc/kvm/book3s_rmhandlers.S
index ab523f3c173..9ecf6e35cd8 100644
--- a/arch/powerpc/kvm/book3s_rmhandlers.S
+++ b/arch/powerpc/kvm/book3s_rmhandlers.S
@@ -67,7 +67,6 @@ kvmppc_skip_Hinterrupt:
#elif defined(CONFIG_PPC_BOOK3S_32)
#define FUNC(name) name
-#define MTMSR_EERI(reg) mtmsr (reg)
.macro INTERRUPT_TRAMPOLINE intno
diff --git a/arch/powerpc/platforms/85xx/p1022_ds.c b/arch/powerpc/platforms/85xx/p1022_ds.c
index 89ee02c5456..3c732acf331 100644
--- a/arch/powerpc/platforms/85xx/p1022_ds.c
+++ b/arch/powerpc/platforms/85xx/p1022_ds.c
@@ -208,6 +208,7 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
u8 __iomem *lbc_lcs0_ba = NULL;
u8 __iomem *lbc_lcs1_ba = NULL;
phys_addr_t cs0_addr, cs1_addr;
+ u32 br0, or0, br1, or1;
const __be32 *iprop;
unsigned int num_laws;
u8 b;
@@ -256,11 +257,70 @@ static void p1022ds_set_monitor_port(enum fsl_diu_monitor_port port)
}
num_laws = be32_to_cpup(iprop);
- cs0_addr = lbc_br_to_phys(ecm, num_laws, in_be32(&lbc->bank[0].br));
- cs1_addr = lbc_br_to_phys(ecm, num_laws, in_be32(&lbc->bank[1].br));
+ /*
+ * Indirect mode requires both BR0 and BR1 to be set to "GPCM",
+ * otherwise writes to these addresses won't actually appear on the
+ * local bus, and so the PIXIS won't see them.
+ *
+ * In FCM mode, writes go to the NAND controller, which does not pass
+ * them to the localbus directly. So we force BR0 and BR1 into GPCM
+ * mode, since we don't care about what's behind the localbus any
+ * more.
+ */
+ br0 = in_be32(&lbc->bank[0].br);
+ br1 = in_be32(&lbc->bank[1].br);
+ or0 = in_be32(&lbc->bank[0].or);
+ or1 = in_be32(&lbc->bank[1].or);
+
+ /* Make sure CS0 and CS1 are programmed */
+ if (!(br0 & BR_V) || !(br1 & BR_V)) {
+ pr_err("p1022ds: CS0 and/or CS1 is not programmed\n");
+ goto exit;
+ }
+
+ /*
+ * Use the existing BRx/ORx values if it's already GPCM. Otherwise,
+ * force the values to simple 32KB GPCM windows with the most
+ * conservative timing.
+ */
+ if ((br0 & BR_MSEL) != BR_MS_GPCM) {
+ br0 = (br0 & BR_BA) | BR_V;
+ or0 = 0xFFFF8000 | 0xFF7;
+ out_be32(&lbc->bank[0].br, br0);
+ out_be32(&lbc->bank[0].or, or0);
+ }
+ if ((br1 & BR_MSEL) != BR_MS_GPCM) {
+ br1 = (br1 & BR_BA) | BR_V;
+ or1 = 0xFFFF8000 | 0xFF7;
+ out_be32(&lbc->bank[1].br, br1);
+ out_be32(&lbc->bank[1].or, or1);
+ }
+
+ cs0_addr = lbc_br_to_phys(ecm, num_laws, br0);
+ if (!cs0_addr) {
+ pr_err("p1022ds: could not determine physical address for CS0"
+ " (BR0=%08x)\n", br0);
+ goto exit;
+ }
+ cs1_addr = lbc_br_to_phys(ecm, num_laws, br1);
+ if (!cs0_addr) {
+ pr_err("p1022ds: could not determine physical address for CS1"
+ " (BR1=%08x)\n", br1);
+ goto exit;
+ }
lbc_lcs0_ba = ioremap(cs0_addr, 1);
+ if (!lbc_lcs0_ba) {
+ pr_err("p1022ds: could not ioremap CS0 address %llx\n",
+ (unsigned long long)cs0_addr);
+ goto exit;
+ }
lbc_lcs1_ba = ioremap(cs1_addr, 1);
+ if (!lbc_lcs1_ba) {
+ pr_err("p1022ds: could not ioremap CS1 address %llx\n",
+ (unsigned long long)cs1_addr);
+ goto exit;
+ }
/* Make sure we're in indirect mode first. */
if ((in_be32(&guts->pmuxcr) & PMUXCR_ELBCDIU_MASK) !=
@@ -419,18 +479,6 @@ void __init p1022_ds_pic_init(void)
#if defined(CONFIG_FB_FSL_DIU) || defined(CONFIG_FB_FSL_DIU_MODULE)
-/*
- * Disables a node in the device tree.
- *
- * This function is called before kmalloc() is available, so the 'new' object
- * should be allocated in the global area. The easiest way is to do that is
- * to allocate one static local variable for each call to this function.
- */
-static void __init disable_one_node(struct device_node *np, struct property *new)
-{
- prom_update_property(np, new);
-}
-
/* TRUE if there is a "video=fslfb" command-line parameter. */
static bool fslfb;
@@ -493,28 +541,58 @@ static void __init p1022_ds_setup_arch(void)
diu_ops.valid_monitor_port = p1022ds_valid_monitor_port;
/*
- * Disable the NOR flash node if there is video=fslfb... command-line
- * parameter. When the DIU is active, NOR flash is unavailable, so we
- * have to disable the node before the MTD driver loads.
+ * Disable the NOR and NAND flash nodes if there is video=fslfb...
+ * command-line parameter. When the DIU is active, the localbus is
+ * unavailable, so we have to disable these nodes before the MTD
+ * driver loads.
*/
if (fslfb) {
struct device_node *np =
of_find_compatible_node(NULL, NULL, "fsl,p1022-elbc");
if (np) {
- np = of_find_compatible_node(np, NULL, "cfi-flash");
- if (np) {
+ struct device_node *np2;
+
+ of_node_get(np);
+ np2 = of_find_compatible_node(np, NULL, "cfi-flash");
+ if (np2) {
static struct property nor_status = {
.name = "status",
.value = "disabled",
.length = sizeof("disabled"),
};
+ /*
+ * prom_update_property() is called before
+ * kmalloc() is available, so the 'new' object
+ * should be allocated in the global area.
+ * The easiest way is to do that is to
+ * allocate one static local variable for each
+ * call to this function.
+ */
pr_info("p1022ds: disabling %s node",
- np->full_name);
- disable_one_node(np, &nor_status);
- of_node_put(np);
+ np2->full_name);
+ prom_update_property(np2, &nor_status);
+ of_node_put(np2);
}
+
+ of_node_get(np);
+ np2 = of_find_compatible_node(np, NULL,
+ "fsl,elbc-fcm-nand");
+ if (np2) {
+ static struct property nand_status = {
+ .name = "status",
+ .value = "disabled",
+ .length = sizeof("disabled"),
+ };
+
+ pr_info("p1022ds: disabling %s node",
+ np2->full_name);
+ prom_update_property(np2, &nand_status);
+ of_node_put(np2);
+ }
+
+ of_node_put(np);
}
}
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index d544d7816df..dba1ce235da 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -186,10 +186,13 @@ static void spufs_prune_dir(struct dentry *dir)
static int spufs_rmdir(struct inode *parent, struct dentry *dir)
{
/* remove all entries */
+ int res;
spufs_prune_dir(dir);
d_drop(dir);
-
- return simple_rmdir(parent, dir);
+ res = simple_rmdir(parent, dir);
+ /* We have to give up the mm_struct */
+ spu_forget(SPUFS_I(dir->d_inode)->i_ctx);
+ return res;
}
static int spufs_fill_dir(struct dentry *dir,
@@ -245,9 +248,6 @@ static int spufs_dir_close(struct inode *inode, struct file *file)
mutex_unlock(&parent->i_mutex);
WARN_ON(ret);
- /* We have to give up the mm_struct */
- spu_forget(ctx);
-
return dcache_dir_close(inode, file);
}
@@ -450,28 +450,24 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
struct spu_context *neighbor;
struct path path = {.mnt = mnt, .dentry = dentry};
- ret = -EPERM;
if ((flags & SPU_CREATE_NOSCHED) &&
!capable(CAP_SYS_NICE))
- goto out_unlock;
+ return -EPERM;
- ret = -EINVAL;
if ((flags & (SPU_CREATE_NOSCHED | SPU_CREATE_ISOLATE))
== SPU_CREATE_ISOLATE)
- goto out_unlock;
+ return -EINVAL;
- ret = -ENODEV;
if ((flags & SPU_CREATE_ISOLATE) && !isolated_loader)
- goto out_unlock;
+ return -ENODEV;
gang = NULL;
neighbor = NULL;
affinity = flags & (SPU_CREATE_AFFINITY_MEM | SPU_CREATE_AFFINITY_SPU);
if (affinity) {
gang = SPUFS_I(inode)->i_gang;
- ret = -EINVAL;
if (!gang)
- goto out_unlock;
+ return -EINVAL;
mutex_lock(&gang->aff_mutex);
neighbor = spufs_assert_affinity(flags, gang, aff_filp);
if (IS_ERR(neighbor)) {
@@ -492,22 +488,12 @@ spufs_create_context(struct inode *inode, struct dentry *dentry,
}
ret = spufs_context_open(&path);
- if (ret < 0) {
+ if (ret < 0)
WARN_ON(spufs_rmdir(inode, dentry));
- if (affinity)
- mutex_unlock(&gang->aff_mutex);
- mutex_unlock(&inode->i_mutex);
- spu_forget(SPUFS_I(dentry->d_inode)->i_ctx);
- goto out;
- }
out_aff_unlock:
if (affinity)
mutex_unlock(&gang->aff_mutex);
-out_unlock:
- mutex_unlock(&inode->i_mutex);
-out:
- dput(dentry);
return ret;
}
@@ -580,18 +566,13 @@ static int spufs_create_gang(struct inode *inode,
int ret;
ret = spufs_mkgang(inode, dentry, mode & S_IRWXUGO);
- if (ret)
- goto out;
-
- ret = spufs_gang_open(&path);
- if (ret < 0) {
- int err = simple_rmdir(inode, dentry);
- WARN_ON(err);
+ if (!ret) {
+ ret = spufs_gang_open(&path);
+ if (ret < 0) {
+ int err = simple_rmdir(inode, dentry);
+ WARN_ON(err);
+ }
}
-
-out:
- mutex_unlock(&inode->i_mutex);
- dput(dentry);
return ret;
}
@@ -601,40 +582,32 @@ static struct file_system_type spufs_type;
long spufs_create(struct path *path, struct dentry *dentry,
unsigned int flags, umode_t mode, struct file *filp)
{
+ struct inode *dir = path->dentry->d_inode;
int ret;
- ret = -EINVAL;
/* check if we are on spufs */
if (path->dentry->d_sb->s_type != &spufs_type)
- goto out;
+ return -EINVAL;
/* don't accept undefined flags */
if (flags & (~SPU_CREATE_FLAG_ALL))
- goto out;
+ return -EINVAL;
/* only threads can be underneath a gang */
- if (path->dentry != path->dentry->d_sb->s_root) {
- if ((flags & SPU_CREATE_GANG) ||
- !SPUFS_I(path->dentry->d_inode)->i_gang)
- goto out;
- }
+ if (path->dentry != path->dentry->d_sb->s_root)
+ if ((flags & SPU_CREATE_GANG) || !SPUFS_I(dir)->i_gang)
+ return -EINVAL;
mode &= ~current_umask();
if (flags & SPU_CREATE_GANG)
- ret = spufs_create_gang(path->dentry->d_inode,
- dentry, path->mnt, mode);
+ ret = spufs_create_gang(dir, dentry, path->mnt, mode);
else
- ret = spufs_create_context(path->dentry->d_inode,
- dentry, path->mnt, flags, mode,
+ ret = spufs_create_context(dir, dentry, path->mnt, flags, mode,
filp);
if (ret >= 0)
- fsnotify_mkdir(path->dentry->d_inode, dentry);
- return ret;
+ fsnotify_mkdir(dir, dentry);
-out:
- mutex_unlock(&path->dentry->d_inode->i_mutex);
- dput(dentry);
return ret;
}
diff --git a/arch/powerpc/platforms/cell/spufs/syscalls.c b/arch/powerpc/platforms/cell/spufs/syscalls.c
index 5665dcc382c..5b7d8ffbf89 100644
--- a/arch/powerpc/platforms/cell/spufs/syscalls.c
+++ b/arch/powerpc/platforms/cell/spufs/syscalls.c
@@ -70,7 +70,7 @@ static long do_spu_create(const char __user *pathname, unsigned int flags,
ret = PTR_ERR(dentry);
if (!IS_ERR(dentry)) {
ret = spufs_create(&path, dentry, flags, mode, neighbor);
- path_put(&path);
+ done_path_create(&path, dentry);
}
return ret;
diff --git a/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h b/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h
index 60c9c0bd5ba..2aa97ddb7b7 100644
--- a/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h
+++ b/arch/powerpc/sysdev/fsl_85xx_cache_ctlr.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2010 Freescale Semiconductor, Inc
+ * Copyright 2009-2010, 2012 Freescale Semiconductor, Inc
*
* QorIQ based Cache Controller Memory Mapped Registers
*
@@ -91,7 +91,7 @@ struct mpc85xx_l2ctlr {
struct sram_parameters {
unsigned int sram_size;
- uint64_t sram_offset;
+ phys_addr_t sram_offset;
};
extern int instantiate_cache_sram(struct platform_device *dev,
diff --git a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
index cedabd0f4bf..68ac3aacb19 100644
--- a/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
+++ b/arch/powerpc/sysdev/fsl_85xx_l2ctlr.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009-2010 Freescale Semiconductor, Inc.
+ * Copyright 2009-2010, 2012 Freescale Semiconductor, Inc.
*
* QorIQ (P1/P2) L2 controller init for Cache-SRAM instantiation
*
@@ -31,24 +31,21 @@ static char *sram_size;
static char *sram_offset;
struct mpc85xx_l2ctlr __iomem *l2ctlr;
-static long get_cache_sram_size(void)
+static int get_cache_sram_params(struct sram_parameters *sram_params)
{
- unsigned long val;
+ unsigned long long addr;
+ unsigned int size;
- if (!sram_size || (strict_strtoul(sram_size, 0, &val) < 0))
+ if (!sram_size || (kstrtouint(sram_size, 0, &size) < 0))
return -EINVAL;
- return val;
-}
-
-static long get_cache_sram_offset(void)
-{
- unsigned long val;
-
- if (!sram_offset || (strict_strtoul(sram_offset, 0, &val) < 0))
+ if (!sram_offset || (kstrtoull(sram_offset, 0, &addr) < 0))
return -EINVAL;
- return val;
+ sram_params->sram_offset = addr;
+ sram_params->sram_size = size;
+
+ return 0;
}
static int __init get_size_from_cmdline(char *str)
@@ -93,17 +90,9 @@ static int __devinit mpc85xx_l2ctlr_of_probe(struct platform_device *dev)
}
l2cache_size = *prop;
- sram_params.sram_size = get_cache_sram_size();
- if ((int)sram_params.sram_size <= 0) {
- dev_err(&dev->dev,
- "Entire L2 as cache, Aborting Cache-SRAM stuff\n");
- return -EINVAL;
- }
-
- sram_params.sram_offset = get_cache_sram_offset();
- if ((int64_t)sram_params.sram_offset <= 0) {
+ if (get_cache_sram_params(&sram_params)) {
dev_err(&dev->dev,
- "Entire L2 as cache, provide a valid sram offset\n");
+ "Entire L2 as cache, provide valid sram offset and size\n");
return -EINVAL;
}
@@ -125,14 +114,14 @@ static int __devinit mpc85xx_l2ctlr_of_probe(struct platform_device *dev)
* Write bits[0-17] to srbar0
*/
out_be32(&l2ctlr->srbar0,
- sram_params.sram_offset & L2SRAM_BAR_MSK_LO18);
+ lower_32_bits(sram_params.sram_offset) & L2SRAM_BAR_MSK_LO18);
/*
* Write bits[18-21] to srbare0
*/
#ifdef CONFIG_PHYS_64BIT
out_be32(&l2ctlr->srbarea0,
- (sram_params.sram_offset >> 32) & L2SRAM_BARE_MSK_HI4);
+ upper_32_bits(sram_params.sram_offset) & L2SRAM_BARE_MSK_HI4);
#endif
clrsetbits_be32(&l2ctlr->ctl, L2CR_L2E, L2CR_L2FI);
diff --git a/arch/powerpc/sysdev/xics/icp-hv.c b/arch/powerpc/sysdev/xics/icp-hv.c
index 253dce98c16..14469cf9df6 100644
--- a/arch/powerpc/sysdev/xics/icp-hv.c
+++ b/arch/powerpc/sysdev/xics/icp-hv.c
@@ -111,7 +111,7 @@ static unsigned int icp_hv_get_irq(void)
if (vec == XICS_IRQ_SPURIOUS)
return NO_IRQ;
- irq = irq_radix_revmap_lookup(xics_host, vec);
+ irq = irq_find_mapping(xics_host, vec);
if (likely(irq != NO_IRQ)) {
xics_push_cppr(vec);
return irq;
diff --git a/arch/powerpc/sysdev/xics/icp-native.c b/arch/powerpc/sysdev/xics/icp-native.c
index 4c79b6fbee1..48861d3fcd0 100644
--- a/arch/powerpc/sysdev/xics/icp-native.c
+++ b/arch/powerpc/sysdev/xics/icp-native.c
@@ -119,7 +119,7 @@ static unsigned int icp_native_get_irq(void)
if (vec == XICS_IRQ_SPURIOUS)
return NO_IRQ;
- irq = irq_radix_revmap_lookup(xics_host, vec);
+ irq = irq_find_mapping(xics_host, vec);
if (likely(irq != NO_IRQ)) {
xics_push_cppr(vec);
return irq;
diff --git a/arch/powerpc/sysdev/xics/xics-common.c b/arch/powerpc/sysdev/xics/xics-common.c
index cd1d18db92c..9049d9f4448 100644
--- a/arch/powerpc/sysdev/xics/xics-common.c
+++ b/arch/powerpc/sysdev/xics/xics-common.c
@@ -329,9 +329,6 @@ static int xics_host_map(struct irq_domain *h, unsigned int virq,
pr_devel("xics: map virq %d, hwirq 0x%lx\n", virq, hw);
- /* Insert the interrupt mapping into the radix tree for fast lookup */
- irq_radix_revmap_insert(xics_host, virq, hw);
-
/* They aren't all level sensitive but we just don't really know */
irq_set_status_flags(virq, IRQ_LEVEL);
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index a39b4690c17..76de6b68487 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -85,10 +85,12 @@ config S390
select HAVE_ARCH_MUTEX_CPU_RELAX
select HAVE_ARCH_JUMP_LABEL if !MARCH_G5
select ARCH_SAVE_PAGE_KEYS if HIBERNATION
+ select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select HAVE_MEMBLOCK
select HAVE_MEMBLOCK_NODE_MAP
select HAVE_CMPXCHG_LOCAL
select ARCH_DISCARD_MEMBLOCK
+ select BUILDTIME_EXTABLE_SORT
select ARCH_INLINE_SPIN_TRYLOCK
select ARCH_INLINE_SPIN_TRYLOCK_BH
select ARCH_INLINE_SPIN_LOCK
@@ -117,6 +119,7 @@ config S390
select ARCH_INLINE_WRITE_UNLOCK_BH
select ARCH_INLINE_WRITE_UNLOCK_IRQ
select ARCH_INLINE_WRITE_UNLOCK_IRQRESTORE
+ select ARCH_WANT_IPC_PARSE_VERSION
select GENERIC_SMP_IDLE_THREAD
select GENERIC_TIME_VSYSCALL
select GENERIC_CLOCKEVENTS
diff --git a/arch/s390/defconfig b/arch/s390/defconfig
index 37d2bf26796..f39cd710980 100644
--- a/arch/s390/defconfig
+++ b/arch/s390/defconfig
@@ -7,13 +7,16 @@ CONFIG_TASK_DELAY_ACCT=y
CONFIG_TASK_XACCT=y
CONFIG_TASK_IO_ACCOUNTING=y
CONFIG_AUDIT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+CONFIG_RCU_FAST_NO_HZ=y
CONFIG_IKCONFIG=y
CONFIG_IKCONFIG_PROC=y
CONFIG_CGROUPS=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
-CONFIG_CGROUP_MEM_RES_CTLR=y
+CONFIG_CGROUP_MEMCG=y
CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
@@ -35,8 +38,6 @@ CONFIG_MODVERSIONS=y
CONFIG_PARTITION_ADVANCED=y
CONFIG_IBM_PARTITION=y
CONFIG_DEFAULT_DEADLINE=y
-CONFIG_NO_HZ=y
-CONFIG_HIGH_RES_TIMERS=y
CONFIG_PREEMPT=y
CONFIG_MEMORY_HOTPLUG=y
CONFIG_MEMORY_HOTREMOVE=y
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h
index 5c63615f134..b749c573365 100644
--- a/arch/s390/include/asm/mmu_context.h
+++ b/arch/s390/include/asm/mmu_context.h
@@ -11,7 +11,6 @@
#include <asm/uaccess.h>
#include <asm/tlbflush.h>
#include <asm/ctl_reg.h>
-#include <asm-generic/mm_hooks.h>
static inline int init_new_context(struct task_struct *tsk,
struct mm_struct *mm)
@@ -58,7 +57,7 @@ static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk)
pgd_t *pgd = mm->pgd;
S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd);
- if (user_mode != HOME_SPACE_MODE) {
+ if (addressing_mode != HOME_SPACE_MODE) {
/* Load primary space page table origin. */
asm volatile(LCTL_OPCODE" 1,1,%0\n"
: : "m" (S390_lowcore.user_asce) );
@@ -91,4 +90,17 @@ static inline void activate_mm(struct mm_struct *prev,
switch_mm(prev, next, current);
}
+static inline void arch_dup_mmap(struct mm_struct *oldmm,
+ struct mm_struct *mm)
+{
+#ifdef CONFIG_64BIT
+ if (oldmm->context.asce_limit < mm->context.asce_limit)
+ crst_table_downgrade(mm, oldmm->context.asce_limit);
+#endif
+}
+
+static inline void arch_exit_mmap(struct mm_struct *mm)
+{
+}
+
#endif /* __S390_MMU_CONTEXT_H */
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h
index c40fa91e38a..11e4e323693 100644
--- a/arch/s390/include/asm/processor.h
+++ b/arch/s390/include/asm/processor.h
@@ -120,7 +120,9 @@ struct stack_frame {
regs->psw.mask = psw_user_bits | PSW_MASK_BA; \
regs->psw.addr = new_psw | PSW_ADDR_AMODE; \
regs->gprs[15] = new_stackp; \
+ __tlb_flush_mm(current->mm); \
crst_table_downgrade(current->mm, 1UL << 31); \
+ update_mm(current->mm, current); \
} while (0)
/* Forward declaration, a strange C thing */
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h
index 57e80534375..e6859d16ee2 100644
--- a/arch/s390/include/asm/setup.h
+++ b/arch/s390/include/asm/setup.h
@@ -60,7 +60,7 @@ void create_mem_hole(struct mem_chunk memory_chunk[], unsigned long addr,
#define SECONDARY_SPACE_MODE 2
#define HOME_SPACE_MODE 3
-extern unsigned int user_mode;
+extern unsigned int addressing_mode;
/*
* Machine features detected in head.S
diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h
index 2e37157ba6a..6756e78f480 100644
--- a/arch/s390/include/asm/unistd.h
+++ b/arch/s390/include/asm/unistd.h
@@ -388,7 +388,6 @@
#define __IGNORE_recvmmsg
#define __IGNORE_sendmmsg
-#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_SYS_ALARM
#define __ARCH_WANT_SYS_GETHOSTNAME
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index 21be961e8a4..ba500d8dc39 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -110,6 +110,7 @@ struct debug_view debug_raw_view = {
NULL,
NULL
};
+EXPORT_SYMBOL(debug_raw_view);
struct debug_view debug_hex_ascii_view = {
"hex_ascii",
@@ -119,6 +120,7 @@ struct debug_view debug_hex_ascii_view = {
NULL,
NULL
};
+EXPORT_SYMBOL(debug_hex_ascii_view);
static struct debug_view debug_level_view = {
"level",
@@ -155,6 +157,7 @@ struct debug_view debug_sprintf_view = {
NULL,
NULL
};
+EXPORT_SYMBOL(debug_sprintf_view);
/* used by dump analysis tools to determine version of debug feature */
static unsigned int __used debug_feature_version = __DEBUG_FEATURE_VERSION;
@@ -730,6 +733,7 @@ debug_info_t *debug_register(const char *name, int pages_per_area,
return debug_register_mode(name, pages_per_area, nr_areas, buf_size,
S_IRUSR | S_IWUSR, 0, 0);
}
+EXPORT_SYMBOL(debug_register);
/*
* debug_unregister:
@@ -748,6 +752,7 @@ debug_unregister(debug_info_t * id)
out:
return;
}
+EXPORT_SYMBOL(debug_unregister);
/*
* debug_set_size:
@@ -810,7 +815,7 @@ debug_set_level(debug_info_t* id, int new_level)
}
spin_unlock_irqrestore(&id->lock,flags);
}
-
+EXPORT_SYMBOL(debug_set_level);
/*
* proceed_active_entry:
@@ -930,7 +935,7 @@ debug_stop_all(void)
if (debug_stoppable)
debug_active = 0;
}
-
+EXPORT_SYMBOL(debug_stop_all);
void debug_set_critical(void)
{
@@ -963,6 +968,7 @@ debug_event_common(debug_info_t * id, int level, const void *buf, int len)
return active;
}
+EXPORT_SYMBOL(debug_event_common);
/*
* debug_exception_common:
@@ -990,6 +996,7 @@ debug_entry_t
return active;
}
+EXPORT_SYMBOL(debug_exception_common);
/*
* counts arguments in format string for sprintf view
@@ -1043,6 +1050,7 @@ debug_sprintf_event(debug_info_t* id, int level,char *string,...)
return active;
}
+EXPORT_SYMBOL(debug_sprintf_event);
/*
* debug_sprintf_exception:
@@ -1081,25 +1089,7 @@ debug_sprintf_exception(debug_info_t* id, int level,char *string,...)
return active;
}
-
-/*
- * debug_init:
- * - is called exactly once to initialize the debug feature
- */
-
-static int
-__init debug_init(void)
-{
- int rc = 0;
-
- s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table);
- mutex_lock(&debug_mutex);
- debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT,NULL);
- initialized = 1;
- mutex_unlock(&debug_mutex);
-
- return rc;
-}
+EXPORT_SYMBOL(debug_sprintf_exception);
/*
* debug_register_view:
@@ -1147,6 +1137,7 @@ debug_register_view(debug_info_t * id, struct debug_view *view)
out:
return rc;
}
+EXPORT_SYMBOL(debug_register_view);
/*
* debug_unregister_view:
@@ -1176,6 +1167,7 @@ debug_unregister_view(debug_info_t * id, struct debug_view *view)
out:
return rc;
}
+EXPORT_SYMBOL(debug_unregister_view);
static inline char *
debug_get_user_string(const char __user *user_buf, size_t user_len)
@@ -1485,6 +1477,7 @@ debug_dflt_header_fn(debug_info_t * id, struct debug_view *view,
except_str, entry->id.fields.cpuid, (void *) caller);
return rc;
}
+EXPORT_SYMBOL(debug_dflt_header_fn);
/*
* prints debug data sprintf-formated:
@@ -1533,33 +1526,16 @@ out:
}
/*
- * clean up module
+ * debug_init:
+ * - is called exactly once to initialize the debug feature
*/
-static void __exit debug_exit(void)
+static int __init debug_init(void)
{
- debugfs_remove(debug_debugfs_root_entry);
- unregister_sysctl_table(s390dbf_sysctl_header);
- return;
+ s390dbf_sysctl_header = register_sysctl_table(s390dbf_dir_table);
+ mutex_lock(&debug_mutex);
+ debug_debugfs_root_entry = debugfs_create_dir(DEBUG_DIR_ROOT, NULL);
+ initialized = 1;
+ mutex_unlock(&debug_mutex);
+ return 0;
}
-
-/*
- * module definitions
- */
postcore_initcall(debug_init);
-module_exit(debug_exit);
-MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(debug_register);
-EXPORT_SYMBOL(debug_unregister);
-EXPORT_SYMBOL(debug_set_level);
-EXPORT_SYMBOL(debug_stop_all);
-EXPORT_SYMBOL(debug_register_view);
-EXPORT_SYMBOL(debug_unregister_view);
-EXPORT_SYMBOL(debug_event_common);
-EXPORT_SYMBOL(debug_exception_common);
-EXPORT_SYMBOL(debug_hex_ascii_view);
-EXPORT_SYMBOL(debug_raw_view);
-EXPORT_SYMBOL(debug_dflt_header_fn);
-EXPORT_SYMBOL(debug_sprintf_view);
-EXPORT_SYMBOL(debug_sprintf_exception);
-EXPORT_SYMBOL(debug_sprintf_event);
diff --git a/arch/s390/kernel/dis.c b/arch/s390/kernel/dis.c
index 1f6b428e276..619c5d35072 100644
--- a/arch/s390/kernel/dis.c
+++ b/arch/s390/kernel/dis.c
@@ -1531,7 +1531,7 @@ static int print_insn(char *buffer, unsigned char *code, unsigned long addr)
void show_code(struct pt_regs *regs)
{
- char *mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl";
+ char *mode = user_mode(regs) ? "User" : "Krnl";
unsigned char code[64];
char buffer[64], *ptr;
mm_segment_t old_fs;
@@ -1540,7 +1540,7 @@ void show_code(struct pt_regs *regs)
/* Get a snapshot of the 64 bytes surrounding the fault address. */
old_fs = get_fs();
- set_fs((regs->psw.mask & PSW_MASK_PSTATE) ? USER_DS : KERNEL_DS);
+ set_fs(user_mode(regs) ? USER_DS : KERNEL_DS);
for (start = 32; start && regs->psw.addr >= 34 - start; start -= 2) {
addr = regs->psw.addr - 34 + start;
if (__copy_from_user(code + start - 2,
diff --git a/arch/s390/kernel/early.c b/arch/s390/kernel/early.c
index bc95a8ebd9c..83c3271c442 100644
--- a/arch/s390/kernel/early.c
+++ b/arch/s390/kernel/early.c
@@ -455,7 +455,6 @@ void __init startup_init(void)
init_kernel_storage_key();
lockdep_init();
lockdep_off();
- sort_main_extable();
setup_lowcore_early();
setup_facility_list();
detect_machine_type();
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index e64d141555c..6ffcd320321 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -1583,7 +1583,7 @@ static struct kset *vmcmd_kset;
static void vmcmd_run(struct shutdown_trigger *trigger)
{
- char *cmd, *next_cmd;
+ char *cmd;
if (strcmp(trigger->name, ON_REIPL_STR) == 0)
cmd = vmcmd_on_reboot;
@@ -1600,15 +1600,7 @@ static void vmcmd_run(struct shutdown_trigger *trigger)
if (strlen(cmd) == 0)
return;
- do {
- next_cmd = strchr(cmd, '\n');
- if (next_cmd) {
- next_cmd[0] = 0;
- next_cmd += 1;
- }
- __cpcmd(cmd, NULL, 0, NULL);
- cmd = next_cmd;
- } while (cmd != NULL);
+ __cpcmd(cmd, NULL, 0, NULL);
}
static int vmcmd_init(void)
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 743c0f32fe3..f86c81e13c3 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -302,8 +302,8 @@ static int __init parse_vmalloc(char *arg)
}
early_param("vmalloc", parse_vmalloc);
-unsigned int user_mode = HOME_SPACE_MODE;
-EXPORT_SYMBOL_GPL(user_mode);
+unsigned int addressing_mode = HOME_SPACE_MODE;
+EXPORT_SYMBOL_GPL(addressing_mode);
static int set_amode_primary(void)
{
@@ -328,7 +328,7 @@ static int set_amode_primary(void)
*/
static int __init early_parse_switch_amode(char *p)
{
- user_mode = PRIMARY_SPACE_MODE;
+ addressing_mode = PRIMARY_SPACE_MODE;
return 0;
}
early_param("switch_amode", early_parse_switch_amode);
@@ -336,9 +336,9 @@ early_param("switch_amode", early_parse_switch_amode);
static int __init early_parse_user_mode(char *p)
{
if (p && strcmp(p, "primary") == 0)
- user_mode = PRIMARY_SPACE_MODE;
+ addressing_mode = PRIMARY_SPACE_MODE;
else if (!p || strcmp(p, "home") == 0)
- user_mode = HOME_SPACE_MODE;
+ addressing_mode = HOME_SPACE_MODE;
else
return 1;
return 0;
@@ -347,7 +347,7 @@ early_param("user_mode", early_parse_user_mode);
static void setup_addressing_mode(void)
{
- if (user_mode == PRIMARY_SPACE_MODE) {
+ if (addressing_mode == PRIMARY_SPACE_MODE) {
if (set_amode_primary())
pr_info("Address spaces switched, "
"mvcos available\n");
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index af2421a0f31..01775c04a90 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -185,7 +185,7 @@ void show_registers(struct pt_regs *regs)
{
char *mode;
- mode = (regs->psw.mask & PSW_MASK_PSTATE) ? "User" : "Krnl";
+ mode = user_mode(regs) ? "User" : "Krnl";
printk("%s PSW : %p %p",
mode, (void *) regs->psw.mask,
(void *) regs->psw.addr);
@@ -225,7 +225,7 @@ void show_regs(struct pt_regs *regs)
(void *) current->thread.ksp);
show_registers(regs);
/* Show stack backtrace if pt_regs is from kernel mode */
- if (!(regs->psw.mask & PSW_MASK_PSTATE))
+ if (!user_mode(regs))
show_trace(NULL, (unsigned long *) regs->gprs[15]);
show_last_breaking_event(regs);
}
@@ -300,7 +300,7 @@ static void __kprobes do_trap(struct pt_regs *regs,
regs->int_code, si_signo) == NOTIFY_STOP)
return;
- if (regs->psw.mask & PSW_MASK_PSTATE) {
+ if (user_mode(regs)) {
info.si_signo = si_signo;
info.si_errno = 0;
info.si_code = si_code;
@@ -341,7 +341,7 @@ void __kprobes do_per_trap(struct pt_regs *regs)
static void default_trap_handler(struct pt_regs *regs)
{
- if (regs->psw.mask & PSW_MASK_PSTATE) {
+ if (user_mode(regs)) {
report_user_fault(regs, SIGSEGV);
do_exit(SIGSEGV);
} else
@@ -410,7 +410,7 @@ static void __kprobes illegal_op(struct pt_regs *regs)
location = get_psw_address(regs);
- if (regs->psw.mask & PSW_MASK_PSTATE) {
+ if (user_mode(regs)) {
if (get_user(*((__u16 *) opcode), (__u16 __user *) location))
return;
if (*((__u16 *) opcode) == S390_BREAKPOINT_U16) {
@@ -478,7 +478,7 @@ void specification_exception(struct pt_regs *regs)
location = (__u16 __user *) get_psw_address(regs);
- if (regs->psw.mask & PSW_MASK_PSTATE) {
+ if (user_mode(regs)) {
get_user(*((__u16 *) opcode), location);
switch (opcode[0]) {
case 0x28: /* LDR Rx,Ry */
@@ -531,7 +531,7 @@ static void data_exception(struct pt_regs *regs)
asm volatile("stfpc %0" : "=m" (current->thread.fp_regs.fpc));
#ifdef CONFIG_MATHEMU
- else if (regs->psw.mask & PSW_MASK_PSTATE) {
+ else if (user_mode(regs)) {
__u8 opcode[6];
get_user(*((__u16 *) opcode), location);
switch (opcode[0]) {
@@ -598,7 +598,7 @@ static void data_exception(struct pt_regs *regs)
static void space_switch_exception(struct pt_regs *regs)
{
/* Set user psw back to home space mode. */
- if (regs->psw.mask & PSW_MASK_PSTATE)
+ if (user_mode(regs))
regs->psw.mask |= PSW_ASC_HOME;
/* Send SIGILL. */
do_trap(regs, SIGILL, ILL_PRVOPC, "space switch event");
diff --git a/arch/s390/kernel/vdso.c b/arch/s390/kernel/vdso.c
index ea5590fdca3..9a19ca367c1 100644
--- a/arch/s390/kernel/vdso.c
+++ b/arch/s390/kernel/vdso.c
@@ -84,7 +84,8 @@ struct vdso_data *vdso_data = &vdso_data_store.data;
*/
static void vdso_init_data(struct vdso_data *vd)
{
- vd->ectg_available = user_mode != HOME_SPACE_MODE && test_facility(31);
+ vd->ectg_available =
+ addressing_mode != HOME_SPACE_MODE && test_facility(31);
}
#ifdef CONFIG_64BIT
@@ -101,7 +102,7 @@ int vdso_alloc_per_cpu(struct _lowcore *lowcore)
lowcore->vdso_per_cpu_data = __LC_PASTE;
- if (user_mode == HOME_SPACE_MODE || !vdso_enabled)
+ if (addressing_mode == HOME_SPACE_MODE || !vdso_enabled)
return 0;
segment_table = __get_free_pages(GFP_KERNEL, SEGMENT_ORDER);
@@ -146,7 +147,7 @@ void vdso_free_per_cpu(struct _lowcore *lowcore)
unsigned long segment_table, page_table, page_frame;
u32 *psal, *aste;
- if (user_mode == HOME_SPACE_MODE || !vdso_enabled)
+ if (addressing_mode == HOME_SPACE_MODE || !vdso_enabled)
return;
psal = (u32 *)(addr_t) lowcore->paste[4];
@@ -164,7 +165,7 @@ static void vdso_init_cr5(void)
{
unsigned long cr5;
- if (user_mode == HOME_SPACE_MODE || !vdso_enabled)
+ if (addressing_mode == HOME_SPACE_MODE || !vdso_enabled)
return;
cr5 = offsetof(struct _lowcore, paste);
__ctl_load(cr5, 5, 5);
diff --git a/arch/s390/kernel/vmlinux.lds.S b/arch/s390/kernel/vmlinux.lds.S
index 21109c63eb1..de8fa9bbd35 100644
--- a/arch/s390/kernel/vmlinux.lds.S
+++ b/arch/s390/kernel/vmlinux.lds.S
@@ -45,7 +45,7 @@ SECTIONS
.dummy : { *(.dummy) } :data
- RODATA
+ RO_DATA_SECTION(PAGE_SIZE)
#ifdef CONFIG_SHARED_KERNEL
. = ALIGN(0x100000); /* VM shared segments are 1MB aligned */
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 6a12d1bb6e0..6c013f54414 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -49,6 +49,7 @@
#define VM_FAULT_BADCONTEXT 0x010000
#define VM_FAULT_BADMAP 0x020000
#define VM_FAULT_BADACCESS 0x040000
+#define VM_FAULT_SIGNAL 0x080000
static unsigned long store_indication;
@@ -110,7 +111,7 @@ static inline int user_space_fault(unsigned long trans_exc_code)
if (trans_exc_code == 2)
/* Access via secondary space, set_fs setting decides */
return current->thread.mm_segment.ar4;
- if (user_mode == HOME_SPACE_MODE)
+ if (addressing_mode == HOME_SPACE_MODE)
/* User space if the access has been done via home space. */
return trans_exc_code == 3;
/*
@@ -219,7 +220,7 @@ static noinline void do_fault_error(struct pt_regs *regs, int fault)
case VM_FAULT_BADACCESS:
case VM_FAULT_BADMAP:
/* Bad memory access. Check if it is kernel or user space. */
- if (regs->psw.mask & PSW_MASK_PSTATE) {
+ if (user_mode(regs)) {
/* User mode accesses just cause a SIGSEGV */
si_code = (fault == VM_FAULT_BADMAP) ?
SEGV_MAPERR : SEGV_ACCERR;
@@ -229,15 +230,19 @@ static noinline void do_fault_error(struct pt_regs *regs, int fault)
case VM_FAULT_BADCONTEXT:
do_no_context(regs);
break;
+ case VM_FAULT_SIGNAL:
+ if (!user_mode(regs))
+ do_no_context(regs);
+ break;
default: /* fault & VM_FAULT_ERROR */
if (fault & VM_FAULT_OOM) {
- if (!(regs->psw.mask & PSW_MASK_PSTATE))
+ if (!user_mode(regs))
do_no_context(regs);
else
pagefault_out_of_memory();
} else if (fault & VM_FAULT_SIGBUS) {
/* Kernel mode? Handle exceptions or die */
- if (!(regs->psw.mask & PSW_MASK_PSTATE))
+ if (!user_mode(regs))
do_no_context(regs);
else
do_sigbus(regs);
@@ -286,7 +291,7 @@ static inline int do_exception(struct pt_regs *regs, int access)
address = trans_exc_code & __FAIL_ADDR_MASK;
perf_sw_event(PERF_COUNT_SW_PAGE_FAULTS, 1, regs, address);
- flags = FAULT_FLAG_ALLOW_RETRY;
+ flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
if (access == VM_WRITE || (trans_exc_code & store_indication) == 0x400)
flags |= FAULT_FLAG_WRITE;
down_read(&mm->mmap_sem);
@@ -335,6 +340,11 @@ retry:
* the fault.
*/
fault = handle_mm_fault(mm, vma, address, flags);
+ /* No reason to continue if interrupted by SIGKILL. */
+ if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) {
+ fault = VM_FAULT_SIGNAL;
+ goto out;
+ }
if (unlikely(fault & VM_FAULT_ERROR))
goto out_up;
@@ -426,7 +436,7 @@ void __kprobes do_asce_exception(struct pt_regs *regs)
}
/* User mode accesses just cause a SIGSEGV */
- if (regs->psw.mask & PSW_MASK_PSTATE) {
+ if (user_mode(regs)) {
do_sigsegv(regs, SEGV_MAPERR);
return;
}
@@ -441,6 +451,7 @@ int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write)
struct pt_regs regs;
int access, fault;
+ /* Emulate a uaccess fault from kernel mode. */
regs.psw.mask = psw_kernel_bits | PSW_MASK_DAT | PSW_MASK_MCHECK;
if (!irqs_disabled())
regs.psw.mask |= PSW_MASK_IO | PSW_MASK_EXT;
@@ -450,12 +461,12 @@ int __handle_fault(unsigned long uaddr, unsigned long pgm_int_code, int write)
regs.int_parm_long = (uaddr & PAGE_MASK) | 2;
access = write ? VM_WRITE : VM_READ;
fault = do_exception(&regs, access);
- if (unlikely(fault)) {
- if (fault & VM_FAULT_OOM)
- return -EFAULT;
- else if (fault & VM_FAULT_SIGBUS)
- do_sigbus(&regs);
- }
+ /*
+ * Since the fault happened in kernel mode while performing a uaccess
+ * all we need to do now is emulating a fixup in case "fault" is not
+ * zero.
+ * For the calling uaccess functions this results always in -EFAULT.
+ */
return fault ? -EFAULT : 0;
}
diff --git a/arch/s390/mm/mmap.c b/arch/s390/mm/mmap.c
index 573384256c5..c59a5efa58b 100644
--- a/arch/s390/mm/mmap.c
+++ b/arch/s390/mm/mmap.c
@@ -103,9 +103,15 @@ void arch_pick_mmap_layout(struct mm_struct *mm)
int s390_mmap_check(unsigned long addr, unsigned long len)
{
+ int rc;
+
if (!is_compat_task() &&
- len >= TASK_SIZE && TASK_SIZE < (1UL << 53))
- return crst_table_upgrade(current->mm, 1UL << 53);
+ len >= TASK_SIZE && TASK_SIZE < (1UL << 53)) {
+ rc = crst_table_upgrade(current->mm, 1UL << 53);
+ if (rc)
+ return rc;
+ update_mm(current->mm, current);
+ }
return 0;
}
@@ -125,6 +131,7 @@ s390_get_unmapped_area(struct file *filp, unsigned long addr,
rc = crst_table_upgrade(mm, 1UL << 53);
if (rc)
return (unsigned long) rc;
+ update_mm(mm, current);
area = arch_get_unmapped_area(filp, addr, len, pgoff, flags);
}
return area;
@@ -147,6 +154,7 @@ s390_get_unmapped_area_topdown(struct file *filp, const unsigned long addr,
rc = crst_table_upgrade(mm, 1UL << 53);
if (rc)
return (unsigned long) rc;
+ update_mm(mm, current);
area = arch_get_unmapped_area_topdown(filp, addr, len,
pgoff, flags);
}
diff --git a/arch/s390/mm/pgtable.c b/arch/s390/mm/pgtable.c
index 1cab221077c..18df31d1f2c 100644
--- a/arch/s390/mm/pgtable.c
+++ b/arch/s390/mm/pgtable.c
@@ -85,7 +85,6 @@ repeat:
crst_table_free(mm, table);
if (mm->context.asce_limit < limit)
goto repeat;
- update_mm(mm, current);
return 0;
}
@@ -93,9 +92,6 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit)
{
pgd_t *pgd;
- if (mm->context.asce_limit <= limit)
- return;
- __tlb_flush_mm(mm);
while (mm->context.asce_limit > limit) {
pgd = mm->pgd;
switch (pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) {
@@ -118,7 +114,6 @@ void crst_table_downgrade(struct mm_struct *mm, unsigned long limit)
mm->task_size = mm->context.asce_limit;
crst_table_free(mm, (unsigned long *) pgd);
}
- update_mm(mm, current);
}
#endif
@@ -801,7 +796,7 @@ int s390_enable_sie(void)
struct mm_struct *mm, *old_mm;
/* Do we have switched amode? If no, we cannot do sie */
- if (user_mode == HOME_SPACE_MODE)
+ if (addressing_mode == HOME_SPACE_MODE)
return -EINVAL;
/* Do we have pgstes? if yes, we are done */
diff --git a/arch/s390/oprofile/backtrace.c b/arch/s390/oprofile/backtrace.c
index c82f62fb9c2..8a6811b2cdb 100644
--- a/arch/s390/oprofile/backtrace.c
+++ b/arch/s390/oprofile/backtrace.c
@@ -58,7 +58,7 @@ void s390_backtrace(struct pt_regs * const regs, unsigned int depth)
unsigned long head;
struct stack_frame* head_sf;
- if (user_mode (regs))
+ if (user_mode(regs))
return;
head = regs->gprs[15];
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig
index a24595d83ad..36f5141e804 100644
--- a/arch/sh/Kconfig
+++ b/arch/sh/Kconfig
@@ -21,6 +21,7 @@ config SUPERH
select HAVE_KERNEL_LZMA
select HAVE_KERNEL_XZ
select HAVE_KERNEL_LZO
+ select ARCH_WANT_IPC_PARSE_VERSION
select HAVE_SYSCALL_TRACEPOINTS
select HAVE_REGS_AND_STACK_ACCESS_API
select HAVE_GENERIC_HARDIRQS
@@ -50,6 +51,7 @@ config SUPERH32
select HAVE_DYNAMIC_FTRACE
select HAVE_FUNCTION_TRACE_MCOUNT_TEST
select HAVE_FTRACE_NMI_ENTER if DYNAMIC_FTRACE
+ select ARCH_WANT_IPC_PARSE_VERSION
select HAVE_FUNCTION_GRAPH_TRACER
select HAVE_ARCH_KGDB
select HAVE_HW_BREAKPOINT
diff --git a/arch/sh/configs/apsh4ad0a_defconfig b/arch/sh/configs/apsh4ad0a_defconfig
index e7583484cc0..95ae23fcfdd 100644
--- a/arch/sh/configs/apsh4ad0a_defconfig
+++ b/arch/sh/configs/apsh4ad0a_defconfig
@@ -11,7 +11,7 @@ CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
-CONFIG_CGROUP_MEM_RES_CTLR=y
+CONFIG_CGROUP_MEMCG=y
CONFIG_BLK_CGROUP=y
CONFIG_NAMESPACES=y
CONFIG_BLK_DEV_INITRD=y
diff --git a/arch/sh/configs/sdk7786_defconfig b/arch/sh/configs/sdk7786_defconfig
index 8a7dd7b59c5..76a76a295d7 100644
--- a/arch/sh/configs/sdk7786_defconfig
+++ b/arch/sh/configs/sdk7786_defconfig
@@ -18,8 +18,8 @@ CONFIG_CPUSETS=y
# CONFIG_PROC_PID_CPUSET is not set
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
-CONFIG_CGROUP_MEM_RES_CTLR=y
-CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
+CONFIG_CGROUP_MEMCG=y
+CONFIG_CGROUP_MEMCG_SWAP=y
CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_BLK_CGROUP=y
diff --git a/arch/sh/configs/se7206_defconfig b/arch/sh/configs/se7206_defconfig
index 72c3fad7383..6bc30ab9fd1 100644
--- a/arch/sh/configs/se7206_defconfig
+++ b/arch/sh/configs/se7206_defconfig
@@ -11,7 +11,7 @@ CONFIG_CGROUP_DEBUG=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
-CONFIG_CGROUP_MEM_RES_CTLR=y
+CONFIG_CGROUP_MEMCG=y
CONFIG_RELAY=y
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
diff --git a/arch/sh/configs/shx3_defconfig b/arch/sh/configs/shx3_defconfig
index 6bb41303689..cd6c519f8fa 100644
--- a/arch/sh/configs/shx3_defconfig
+++ b/arch/sh/configs/shx3_defconfig
@@ -13,7 +13,7 @@ CONFIG_CGROUP_FREEZER=y
CONFIG_CGROUP_DEVICE=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
-CONFIG_CGROUP_MEM_RES_CTLR=y
+CONFIG_CGROUP_MEMCG=y
CONFIG_RELAY=y
CONFIG_NAMESPACES=y
CONFIG_UTS_NS=y
diff --git a/arch/sh/configs/urquell_defconfig b/arch/sh/configs/urquell_defconfig
index 8bfa4d056d7..d7f89be9f47 100644
--- a/arch/sh/configs/urquell_defconfig
+++ b/arch/sh/configs/urquell_defconfig
@@ -15,8 +15,8 @@ CONFIG_CPUSETS=y
# CONFIG_PROC_PID_CPUSET is not set
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
-CONFIG_CGROUP_MEM_RES_CTLR=y
-CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
+CONFIG_CGROUP_MEMCG=y
+CONFIG_CGROUP_MEMCG_SWAP=y
CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_BLK_DEV_INITRD=y
diff --git a/arch/sh/include/asm/unistd.h b/arch/sh/include/asm/unistd.h
index e800a38c9f8..7bc67076baa 100644
--- a/arch/sh/include/asm/unistd.h
+++ b/arch/sh/include/asm/unistd.h
@@ -6,7 +6,6 @@
# endif
# define __ARCH_WANT_SYS_RT_SIGSUSPEND
-# define __ARCH_WANT_IPC_PARSE_VERSION
# define __ARCH_WANT_OLD_READDIR
# define __ARCH_WANT_OLD_STAT
# define __ARCH_WANT_STAT64
diff --git a/arch/sparc/Kconfig b/arch/sparc/Kconfig
index e74ff137762..67f1f6f5f4e 100644
--- a/arch/sparc/Kconfig
+++ b/arch/sparc/Kconfig
@@ -27,6 +27,7 @@ config SPARC
select HAVE_ARCH_JUMP_LABEL
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_SHOW
+ select ARCH_WANT_IPC_PARSE_VERSION
select USE_GENERIC_SMP_HELPERS if SMP
select GENERIC_PCI_IOMAP
select HAVE_NMI_WATCHDOG if SPARC64
diff --git a/arch/sparc/include/asm/unistd.h b/arch/sparc/include/asm/unistd.h
index c7cb0af0eb5..fb269346480 100644
--- a/arch/sparc/include/asm/unistd.h
+++ b/arch/sparc/include/asm/unistd.h
@@ -423,7 +423,6 @@
#endif
#ifdef __KERNEL__
-#define __ARCH_WANT_IPC_PARSE_VERSION
#define __ARCH_WANT_OLD_READDIR
#define __ARCH_WANT_STAT64
#define __ARCH_WANT_SYS_ALARM
diff --git a/arch/sparc/kernel/ldc.c b/arch/sparc/kernel/ldc.c
index 435e406fdec..81d92fc9983 100644
--- a/arch/sparc/kernel/ldc.c
+++ b/arch/sparc/kernel/ldc.c
@@ -1250,14 +1250,12 @@ int ldc_bind(struct ldc_channel *lp, const char *name)
snprintf(lp->rx_irq_name, LDC_IRQ_NAME_MAX, "%s RX", name);
snprintf(lp->tx_irq_name, LDC_IRQ_NAME_MAX, "%s TX", name);
- err = request_irq(lp->cfg.rx_irq, ldc_rx,
- IRQF_SAMPLE_RANDOM | IRQF_DISABLED,
+ err = request_irq(lp->cfg.rx_irq, ldc_rx, IRQF_DISABLED,
lp->rx_irq_name, lp);
if (err)
return err;
- err = request_irq(lp->cfg.tx_irq, ldc_tx,
- IRQF_SAMPLE_RANDOM | IRQF_DISABLED,
+ err = request_irq(lp->cfg.tx_irq, ldc_tx, IRQF_DISABLED,
lp->tx_irq_name, lp);
if (err) {
free_irq(lp->cfg.rx_irq, lp);
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c
index c38e5aaae56..0dc1f578608 100644
--- a/arch/sparc/kernel/sys_sparc_64.c
+++ b/arch/sparc/kernel/sys_sparc_64.c
@@ -470,7 +470,7 @@ SYSCALL_DEFINE6(sparc_ipc, unsigned int, call, int, first, unsigned long, second
switch (call) {
case SHMAT: {
ulong raddr;
- err = do_shmat(first, ptr, (int)second, &raddr);
+ err = do_shmat(first, ptr, (int)second, &raddr, SHMLBA);
if (!err) {
if (put_user(raddr,
(ulong __user *) third))
diff --git a/arch/tile/configs/tilegx_defconfig b/arch/tile/configs/tilegx_defconfig
index b8d99aca543..0270620a169 100644
--- a/arch/tile/configs/tilegx_defconfig
+++ b/arch/tile/configs/tilegx_defconfig
@@ -18,8 +18,8 @@ CONFIG_CGROUP_DEVICE=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
-CONFIG_CGROUP_MEM_RES_CTLR=y
-CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
+CONFIG_CGROUP_MEMCG=y
+CONFIG_CGROUP_MEMCG_SWAP=y
CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_BLK_CGROUP=y
diff --git a/arch/tile/configs/tilepro_defconfig b/arch/tile/configs/tilepro_defconfig
index 2b1fd31894f..c11de27a9bc 100644
--- a/arch/tile/configs/tilepro_defconfig
+++ b/arch/tile/configs/tilepro_defconfig
@@ -17,8 +17,8 @@ CONFIG_CGROUP_DEVICE=y
CONFIG_CPUSETS=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
-CONFIG_CGROUP_MEM_RES_CTLR=y
-CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
+CONFIG_CGROUP_MEMCG=y
+CONFIG_CGROUP_MEMCG_SWAP=y
CONFIG_CGROUP_SCHED=y
CONFIG_RT_GROUP_SCHED=y
CONFIG_BLK_CGROUP=y
diff --git a/arch/tile/include/asm/Kbuild b/arch/tile/include/asm/Kbuild
index fb7c65ae8de..5bd71994452 100644
--- a/arch/tile/include/asm/Kbuild
+++ b/arch/tile/include/asm/Kbuild
@@ -16,7 +16,6 @@ generic-y += fb.h
generic-y += fcntl.h
generic-y += ioctl.h
generic-y += ioctls.h
-generic-y += ipc.h
generic-y += ipcbuf.h
generic-y += irq_regs.h
generic-y += kdebug.h
diff --git a/arch/um/defconfig b/arch/um/defconfig
index 7823ab12e6a..08107a79506 100644
--- a/arch/um/defconfig
+++ b/arch/um/defconfig
@@ -155,15 +155,15 @@ CONFIG_CPUSETS=y
CONFIG_PROC_PID_CPUSET=y
CONFIG_CGROUP_CPUACCT=y
CONFIG_RESOURCE_COUNTERS=y
-CONFIG_CGROUP_MEM_RES_CTLR=y
-CONFIG_CGROUP_MEM_RES_CTLR_SWAP=y
-# CONFIG_CGROUP_MEM_RES_CTLR_SWAP_ENABLED is not set
-# CONFIG_CGROUP_MEM_RES_CTLR_KMEM is not set
+CONFIG_CGROUP_MEMCG=y
+CONFIG_CGROUP_MEMCG_SWAP=y
+# CONFIG_CGROUP_MEMCG_SWAP_ENABLED is not set
+# CONFIG_CGROUP_MEMCG_KMEM is not set
CONFIG_CGROUP_SCHED=y
CONFIG_FAIR_GROUP_SCHED=y
# CONFIG_CFS_BANDWIDTH is not set
# CONFIG_RT_GROUP_SCHED is not set
-CONFIG_BLK_CGROUP=m
+CONFIG_BLK_CGROUP=y
# CONFIG_DEBUG_BLK_CGROUP is not set
# CONFIG_CHECKPOINT_RESTORE is not set
CONFIG_NAMESPACES=y
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 45e248c2f43..87eebfe03c6 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -150,9 +150,11 @@ void chan_enable_winch(struct chan *chan, struct tty_struct *tty)
static void line_timer_cb(struct work_struct *work)
{
struct line *line = container_of(work, struct line, task.work);
+ struct tty_struct *tty = tty_port_tty_get(&line->port);
if (!line->throttled)
- chan_interrupt(line, line->tty, line->driver->read_irq);
+ chan_interrupt(line, tty, line->driver->read_irq);
+ tty_kref_put(tty);
}
int enable_chan(struct line *line)
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index acfd0e0fd0c..bbaf2c59830 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -19,9 +19,11 @@ static irqreturn_t line_interrupt(int irq, void *data)
{
struct chan *chan = data;
struct line *line = chan->line;
+ struct tty_struct *tty = tty_port_tty_get(&line->port);
if (line)
- chan_interrupt(line, line->tty, irq);
+ chan_interrupt(line, tty, irq);
+ tty_kref_put(tty);
return IRQ_HANDLED;
}
@@ -219,92 +221,6 @@ void line_set_termios(struct tty_struct *tty, struct ktermios * old)
/* nothing */
}
-static const struct {
- int cmd;
- char *level;
- char *name;
-} tty_ioctls[] = {
- /* don't print these, they flood the log ... */
- { TCGETS, NULL, "TCGETS" },
- { TCSETS, NULL, "TCSETS" },
- { TCSETSW, NULL, "TCSETSW" },
- { TCFLSH, NULL, "TCFLSH" },
- { TCSBRK, NULL, "TCSBRK" },
-
- /* general tty stuff */
- { TCSETSF, KERN_DEBUG, "TCSETSF" },
- { TCGETA, KERN_DEBUG, "TCGETA" },
- { TIOCMGET, KERN_DEBUG, "TIOCMGET" },
- { TCSBRKP, KERN_DEBUG, "TCSBRKP" },
- { TIOCMSET, KERN_DEBUG, "TIOCMSET" },
-
- /* linux-specific ones */
- { TIOCLINUX, KERN_INFO, "TIOCLINUX" },
- { KDGKBMODE, KERN_INFO, "KDGKBMODE" },
- { KDGKBTYPE, KERN_INFO, "KDGKBTYPE" },
- { KDSIGACCEPT, KERN_INFO, "KDSIGACCEPT" },
-};
-
-int line_ioctl(struct tty_struct *tty, unsigned int cmd,
- unsigned long arg)
-{
- int ret;
- int i;
-
- ret = 0;
- switch(cmd) {
-#ifdef TIOCGETP
- case TIOCGETP:
- case TIOCSETP:
- case TIOCSETN:
-#endif
-#ifdef TIOCGETC
- case TIOCGETC:
- case TIOCSETC:
-#endif
-#ifdef TIOCGLTC
- case TIOCGLTC:
- case TIOCSLTC:
-#endif
- /* Note: these are out of date as we now have TCGETS2 etc but this
- whole lot should probably go away */
- case TCGETS:
- case TCSETSF:
- case TCSETSW:
- case TCSETS:
- case TCGETA:
- case TCSETAF:
- case TCSETAW:
- case TCSETA:
- case TCXONC:
- case TCFLSH:
- case TIOCOUTQ:
- case TIOCINQ:
- case TIOCGLCKTRMIOS:
- case TIOCSLCKTRMIOS:
- case TIOCPKT:
- case TIOCGSOFTCAR:
- case TIOCSSOFTCAR:
- return -ENOIOCTLCMD;
-#if 0
- case TCwhatever:
- /* do something */
- break;
-#endif
- default:
- for (i = 0; i < ARRAY_SIZE(tty_ioctls); i++)
- if (cmd == tty_ioctls[i].cmd)
- break;
- if (i == ARRAY_SIZE(tty_ioctls)) {
- printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n",
- __func__, tty->name, cmd);
- }
- ret = -ENOIOCTLCMD;
- break;
- }
- return ret;
-}
-
void line_throttle(struct tty_struct *tty)
{
struct line *line = tty->driver_data;
@@ -333,7 +249,7 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
{
struct chan *chan = data;
struct line *line = chan->line;
- struct tty_struct *tty = line->tty;
+ struct tty_struct *tty;
int err;
/*
@@ -352,68 +268,42 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
}
spin_unlock(&line->lock);
+ tty = tty_port_tty_get(&line->port);
if (tty == NULL)
return IRQ_NONE;
tty_wakeup(tty);
+ tty_kref_put(tty);
+
return IRQ_HANDLED;
}
int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
{
const struct line_driver *driver = line->driver;
- int err = 0, flags = IRQF_SHARED | IRQF_SAMPLE_RANDOM;
+ int err = 0;
if (input)
err = um_request_irq(driver->read_irq, fd, IRQ_READ,
- line_interrupt, flags,
- driver->read_irq_name, data);
+ line_interrupt, IRQF_SHARED,
+ driver->read_irq_name, data);
if (err)
return err;
if (output)
err = um_request_irq(driver->write_irq, fd, IRQ_WRITE,
- line_write_interrupt, flags,
- driver->write_irq_name, data);
+ line_write_interrupt, IRQF_SHARED,
+ driver->write_irq_name, data);
return err;
}
-/*
- * Normally, a driver like this can rely mostly on the tty layer
- * locking, particularly when it comes to the driver structure.
- * However, in this case, mconsole requests can come in "from the
- * side", and race with opens and closes.
- *
- * mconsole config requests will want to be sure the device isn't in
- * use, and get_config, open, and close will want a stable
- * configuration. The checking and modification of the configuration
- * is done under a spinlock. Checking whether the device is in use is
- * line->tty->count > 1, also under the spinlock.
- *
- * line->count serves to decide whether the device should be enabled or
- * disabled on the host. If it's equal to 0, then we are doing the
- * first open or last close. Otherwise, open and close just return.
- */
-
-int line_open(struct line *lines, struct tty_struct *tty)
+static int line_activate(struct tty_port *port, struct tty_struct *tty)
{
- struct line *line = &lines[tty->index];
- int err = -ENODEV;
-
- mutex_lock(&line->count_lock);
- if (!line->valid)
- goto out_unlock;
-
- err = 0;
- if (line->count++)
- goto out_unlock;
-
- BUG_ON(tty->driver_data);
- tty->driver_data = line;
- line->tty = tty;
+ int ret;
+ struct line *line = tty->driver_data;
- err = enable_chan(line);
- if (err) /* line_close() will be called by our caller */
- goto out_unlock;
+ ret = enable_chan(line);
+ if (ret)
+ return ret;
if (!line->sigio) {
chan_enable_winch(line->chan_out, tty);
@@ -421,44 +311,60 @@ int line_open(struct line *lines, struct tty_struct *tty)
}
chan_window_size(line, &tty->winsize.ws_row,
- &tty->winsize.ws_col);
-out_unlock:
- mutex_unlock(&line->count_lock);
- return err;
+ &tty->winsize.ws_col);
+
+ return 0;
}
-static void unregister_winch(struct tty_struct *tty);
+static const struct tty_port_operations line_port_ops = {
+ .activate = line_activate,
+};
-void line_close(struct tty_struct *tty, struct file * filp)
+int line_open(struct tty_struct *tty, struct file *filp)
{
struct line *line = tty->driver_data;
- /*
- * If line_open fails (and tty->driver_data is never set),
- * tty_open will call line_close. So just return in this case.
- */
- if (line == NULL)
- return;
+ return tty_port_open(&line->port, tty, filp);
+}
- /* We ignore the error anyway! */
- flush_buffer(line);
+int line_install(struct tty_driver *driver, struct tty_struct *tty,
+ struct line *line)
+{
+ int ret;
- mutex_lock(&line->count_lock);
- BUG_ON(!line->valid);
+ ret = tty_standard_install(driver, tty);
+ if (ret)
+ return ret;
- if (--line->count)
- goto out_unlock;
+ tty->driver_data = line;
- line->tty = NULL;
- tty->driver_data = NULL;
+ return 0;
+}
+
+static void unregister_winch(struct tty_struct *tty);
+
+void line_cleanup(struct tty_struct *tty)
+{
+ struct line *line = tty->driver_data;
if (line->sigio) {
unregister_winch(tty);
line->sigio = 0;
}
+}
+
+void line_close(struct tty_struct *tty, struct file * filp)
+{
+ struct line *line = tty->driver_data;
-out_unlock:
- mutex_unlock(&line->count_lock);
+ tty_port_close(&line->port, tty, filp);
+}
+
+void line_hangup(struct tty_struct *tty)
+{
+ struct line *line = tty->driver_data;
+
+ tty_port_hangup(&line->port);
}
void close_lines(struct line *lines, int nlines)
@@ -476,9 +382,7 @@ int setup_one_line(struct line *lines, int n, char *init,
struct tty_driver *driver = line->driver->driver;
int err = -EINVAL;
- mutex_lock(&line->count_lock);
-
- if (line->count) {
+ if (line->port.count) {
*error_out = "Device is already open";
goto out;
}
@@ -519,7 +423,6 @@ int setup_one_line(struct line *lines, int n, char *init,
}
}
out:
- mutex_unlock(&line->count_lock);
return err;
}
@@ -607,13 +510,17 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
line = &lines[dev];
- mutex_lock(&line->count_lock);
if (!line->valid)
CONFIG_CHUNK(str, size, n, "none", 1);
- else if (line->tty == NULL)
- CONFIG_CHUNK(str, size, n, line->init_str, 1);
- else n = chan_config_string(line, str, size, error_out);
- mutex_unlock(&line->count_lock);
+ else {
+ struct tty_struct *tty = tty_port_tty_get(&line->port);
+ if (tty == NULL) {
+ CONFIG_CHUNK(str, size, n, line->init_str, 1);
+ } else {
+ n = chan_config_string(line, str, size, error_out);
+ tty_kref_put(tty);
+ }
+ }
return n;
}
@@ -663,8 +570,9 @@ int register_lines(struct line_driver *line_driver,
driver->init_termios = tty_std_termios;
for (i = 0; i < nlines; i++) {
+ tty_port_init(&lines[i].port);
+ lines[i].port.ops = &line_port_ops;
spin_lock_init(&lines[i].lock);
- mutex_init(&lines[i].count_lock);
lines[i].driver = line_driver;
INIT_LIST_HEAD(&lines[i].chan_list);
}
@@ -779,8 +687,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty,
.stack = stack });
if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
- IRQF_SHARED | IRQF_SAMPLE_RANDOM,
- "winch", winch) < 0) {
+ IRQF_SHARED, "winch", winch) < 0) {
printk(KERN_ERR "register_winch_irq - failed to register "
"IRQ\n");
goto out_free;
diff --git a/arch/um/drivers/line.h b/arch/um/drivers/line.h
index 0a1834719db..bae95611e7a 100644
--- a/arch/um/drivers/line.h
+++ b/arch/um/drivers/line.h
@@ -32,9 +32,7 @@ struct line_driver {
};
struct line {
- struct tty_struct *tty;
- struct mutex count_lock;
- unsigned long count;
+ struct tty_port port;
int valid;
char *init_str;
@@ -59,7 +57,11 @@ struct line {
};
extern void line_close(struct tty_struct *tty, struct file * filp);
-extern int line_open(struct line *lines, struct tty_struct *tty);
+extern int line_open(struct tty_struct *tty, struct file *filp);
+extern int line_install(struct tty_driver *driver, struct tty_struct *tty,
+ struct line *line);
+extern void line_cleanup(struct tty_struct *tty);
+extern void line_hangup(struct tty_struct *tty);
extern int line_setup(char **conf, unsigned nlines, char **def,
char *init, char *name);
extern int line_write(struct tty_struct *tty, const unsigned char *buf,
@@ -70,8 +72,6 @@ extern int line_chars_in_buffer(struct tty_struct *tty);
extern void line_flush_buffer(struct tty_struct *tty);
extern void line_flush_chars(struct tty_struct *tty);
extern int line_write_room(struct tty_struct *tty);
-extern int line_ioctl(struct tty_struct *tty, unsigned int cmd,
- unsigned long arg);
extern void line_throttle(struct tty_struct *tty);
extern void line_unthrottle(struct tty_struct *tty);
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index 43b39d61b53..664a60e8dfb 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -774,8 +774,7 @@ static int __init mconsole_init(void)
register_reboot_notifier(&reboot_notifier);
err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt,
- IRQF_SHARED | IRQF_SAMPLE_RANDOM,
- "mconsole", (void *)sock);
+ IRQF_SHARED, "mconsole", (void *)sock);
if (err) {
printk(KERN_ERR "Failed to get IRQ for management console\n");
goto out;
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
index 11866ffd45a..1d83d50236e 100644
--- a/arch/um/drivers/port_kern.c
+++ b/arch/um/drivers/port_kern.c
@@ -100,8 +100,7 @@ static int port_accept(struct port_list *port)
.port = port });
if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt,
- IRQF_SHARED | IRQF_SAMPLE_RANDOM,
- "telnetd", conn)) {
+ IRQF_SHARED, "telnetd", conn)) {
printk(KERN_ERR "port_accept : failed to get IRQ for "
"telnetd\n");
goto out_free;
@@ -184,8 +183,7 @@ void *port_data(int port_num)
}
if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt,
- IRQF_SHARED | IRQF_SAMPLE_RANDOM,
- "port", port)) {
+ IRQF_SHARED, "port", port)) {
printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num);
goto out_close;
}
diff --git a/arch/um/drivers/random.c b/arch/um/drivers/random.c
index b25296e6218..e32c6aa6396 100644
--- a/arch/um/drivers/random.c
+++ b/arch/um/drivers/random.c
@@ -131,8 +131,7 @@ static int __init rng_init (void)
random_fd = err;
err = um_request_irq(RANDOM_IRQ, random_fd, IRQ_READ, random_interrupt,
- IRQF_SAMPLE_RANDOM, "random",
- NULL);
+ 0, "random", NULL);
if (err)
goto err_out_cleanup_hw;
diff --git a/arch/um/drivers/ssl.c b/arch/um/drivers/ssl.c
index e09801a1327..7e86f007012 100644
--- a/arch/um/drivers/ssl.c
+++ b/arch/um/drivers/ssl.c
@@ -87,40 +87,13 @@ static int ssl_remove(int n, char **error_out)
error_out);
}
-static int ssl_open(struct tty_struct *tty, struct file *filp)
-{
- int err = line_open(serial_lines, tty);
-
- if (err)
- printk(KERN_ERR "Failed to open serial line %d, err = %d\n",
- tty->index, err);
-
- return err;
-}
-
-#if 0
-static void ssl_flush_buffer(struct tty_struct *tty)
-{
- return;
-}
-
-static void ssl_stop(struct tty_struct *tty)
-{
- printk(KERN_ERR "Someone should implement ssl_stop\n");
-}
-
-static void ssl_start(struct tty_struct *tty)
-{
- printk(KERN_ERR "Someone should implement ssl_start\n");
-}
-
-void ssl_hangup(struct tty_struct *tty)
+static int ssl_install(struct tty_driver *driver, struct tty_struct *tty)
{
+ return line_install(driver, tty, &serial_lines[tty->index]);
}
-#endif
static const struct tty_operations ssl_ops = {
- .open = ssl_open,
+ .open = line_open,
.close = line_close,
.write = line_write,
.put_char = line_put_char,
@@ -129,14 +102,11 @@ static const struct tty_operations ssl_ops = {
.flush_buffer = line_flush_buffer,
.flush_chars = line_flush_chars,
.set_termios = line_set_termios,
- .ioctl = line_ioctl,
.throttle = line_throttle,
.unthrottle = line_unthrottle,
-#if 0
- .stop = ssl_stop,
- .start = ssl_start,
- .hangup = ssl_hangup,
-#endif
+ .install = ssl_install,
+ .cleanup = line_cleanup,
+ .hangup = line_hangup,
};
/* Changed by ssl_init and referenced by ssl_exit, which are both serialized
diff --git a/arch/um/drivers/stdio_console.c b/arch/um/drivers/stdio_console.c
index 7663541c372..929b99a261f 100644
--- a/arch/um/drivers/stdio_console.c
+++ b/arch/um/drivers/stdio_console.c
@@ -89,21 +89,17 @@ static int con_remove(int n, char **error_out)
return line_remove(vts, ARRAY_SIZE(vts), n, error_out);
}
-static int con_open(struct tty_struct *tty, struct file *filp)
-{
- int err = line_open(vts, tty);
- if (err)
- printk(KERN_ERR "Failed to open console %d, err = %d\n",
- tty->index, err);
-
- return err;
-}
-
/* Set in an initcall, checked in an exitcall */
static int con_init_done = 0;
+static int con_install(struct tty_driver *driver, struct tty_struct *tty)
+{
+ return line_install(driver, tty, &vts[tty->index]);
+}
+
static const struct tty_operations console_ops = {
- .open = con_open,
+ .open = line_open,
+ .install = con_install,
.close = line_close,
.write = line_write,
.put_char = line_put_char,
@@ -112,9 +108,10 @@ static const struct tty_operations console_ops = {
.flush_buffer = line_flush_buffer,
.flush_chars = line_flush_chars,
.set_termios = line_set_termios,
- .ioctl = line_ioctl,
.throttle = line_throttle,
.unthrottle = line_unthrottle,
+ .cleanup = line_cleanup,
+ .hangup = line_hangup,
};
static void uml_console_write(struct console *console, const char *string,
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 20505cafa29..0643e5bc9f4 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -514,7 +514,7 @@ static inline int ubd_file_size(struct ubd *ubd_dev, __u64 *size_out)
goto out;
}
- fd = os_open_file(ubd_dev->file, global_openflags, 0);
+ fd = os_open_file(ubd_dev->file, of_read(OPENFLAGS()), 0);
if (fd < 0)
return fd;
diff --git a/arch/um/drivers/xterm_kern.c b/arch/um/drivers/xterm_kern.c
index b68bbe269e0..e3031e69445 100644
--- a/arch/um/drivers/xterm_kern.c
+++ b/arch/um/drivers/xterm_kern.c
@@ -50,8 +50,7 @@ int xterm_fd(int socket, int *pid_out)
init_completion(&data->ready);
err = um_request_irq(XTERM_IRQ, socket, IRQ_READ, xterm_interrupt,
- IRQF_SHARED | IRQF_SAMPLE_RANDOM,
- "xterm", data);
+ IRQF_SHARED, "xterm", data);
if (err) {
printk(KERN_ERR "xterm_fd : failed to get IRQ for xterm, "
"err = %d\n", err);
diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h
index e786a6a3ec5..442f1d025dc 100644
--- a/arch/um/include/asm/ptrace-generic.h
+++ b/arch/um/include/asm/ptrace-generic.h
@@ -37,6 +37,8 @@ extern int putreg(struct task_struct *child, int regno, unsigned long value);
extern int arch_copy_tls(struct task_struct *new);
extern void clear_flushed_tls(struct task_struct *task);
+extern void syscall_trace_enter(struct pt_regs *regs);
+extern void syscall_trace_leave(struct pt_regs *regs);
#endif
diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h
index 896e1660217..86daa546181 100644
--- a/arch/um/include/shared/as-layout.h
+++ b/arch/um/include/shared/as-layout.h
@@ -60,7 +60,8 @@ extern unsigned long host_task_size;
extern int linux_main(int argc, char **argv);
-extern void (*sig_info[])(int, struct uml_pt_regs *);
+struct siginfo;
+extern void (*sig_info[])(int, struct siginfo *si, struct uml_pt_regs *);
#endif
diff --git a/arch/um/include/shared/irq_user.h b/arch/um/include/shared/irq_user.h
index c6c784df267..2b6d703925b 100644
--- a/arch/um/include/shared/irq_user.h
+++ b/arch/um/include/shared/irq_user.h
@@ -20,7 +20,8 @@ struct irq_fd {
enum { IRQ_READ, IRQ_WRITE };
-extern void sigio_handler(int sig, struct uml_pt_regs *regs);
+struct siginfo;
+extern void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs);
extern void free_irq_by_fd(int fd);
extern void reactivate_fd(int fd, int irqnum);
extern void deactivate_fd(int fd, int irqnum);
diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h
index 00965d06d2c..af6b6dc868b 100644
--- a/arch/um/include/shared/kern_util.h
+++ b/arch/um/include/shared/kern_util.h
@@ -9,6 +9,8 @@
#include "sysdep/ptrace.h"
#include "sysdep/faultinfo.h"
+struct siginfo;
+
extern int uml_exitcode;
extern int ncpus;
@@ -22,7 +24,7 @@ extern void free_stack(unsigned long stack, int order);
extern int do_signal(void);
extern void interrupt_end(void);
-extern void relay_signal(int sig, struct uml_pt_regs *regs);
+extern void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs);
extern unsigned long segv(struct faultinfo fi, unsigned long ip,
int is_user, struct uml_pt_regs *regs);
@@ -33,9 +35,8 @@ extern unsigned int do_IRQ(int irq, struct uml_pt_regs *regs);
extern int smp_sigio_handler(void);
extern void initial_thread_cb(void (*proc)(void *), void *arg);
extern int is_syscall(unsigned long addr);
-extern void timer_handler(int sig, struct uml_pt_regs *regs);
-extern void timer_handler(int sig, struct uml_pt_regs *regs);
+extern void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs);
extern int start_uml(void);
extern void paging_init(void);
@@ -59,9 +60,9 @@ extern unsigned long from_irq_stack(int nested);
extern void syscall_trace(struct uml_pt_regs *regs, int entryexit);
extern int singlestepping(void *t);
-extern void segv_handler(int sig, struct uml_pt_regs *regs);
-extern void bus_handler(int sig, struct uml_pt_regs *regs);
-extern void winch(int sig, struct uml_pt_regs *regs);
+extern void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs);
+extern void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs);
+extern void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs);
extern void fatal_sigsegv(void) __attribute__ ((noreturn));
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 00506c3d5d6..9883026f073 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -30,7 +30,7 @@ static struct irq_fd **last_irq_ptr = &active_fds;
extern void free_irqs(void);
-void sigio_handler(int sig, struct uml_pt_regs *regs)
+void sigio_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
{
struct irq_fd *irq_fd;
int n;
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index ccb9a9d283f..57fc7028714 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -151,12 +151,10 @@ void new_thread_handler(void)
* 0 if it just exits
*/
n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
- if (n == 1) {
- /* Handle any immediate reschedules or signals */
- interrupt_end();
+ if (n == 1)
userspace(&current->thread.regs.regs);
- }
- else do_exit(0);
+ else
+ do_exit(0);
}
/* Called magically, see new_thread_handler above */
@@ -175,9 +173,6 @@ void fork_handler(void)
current->thread.prev_sched = NULL;
- /* Handle any immediate reschedules or signals */
- interrupt_end();
-
userspace(&current->thread.regs.regs);
}
@@ -193,7 +188,7 @@ int copy_thread(unsigned long clone_flags, unsigned long sp,
if (current->thread.forking) {
memcpy(&p->thread.regs.regs, &regs->regs,
sizeof(p->thread.regs.regs));
- UPT_SET_SYSCALL_RETURN(&p->thread.regs.regs, 0);
+ PT_REGS_SET_SYSCALL_RETURN(&p->thread.regs, 0);
if (sp != 0)
REGS_SP(p->thread.regs.regs.gp) = sp;
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 06b19039050..694d551c889 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -3,11 +3,12 @@
* Licensed under the GPL
*/
-#include "linux/audit.h"
-#include "linux/ptrace.h"
-#include "linux/sched.h"
-#include "asm/uaccess.h"
-#include "skas_ptrace.h"
+#include <linux/audit.h>
+#include <linux/ptrace.h>
+#include <linux/sched.h>
+#include <linux/tracehook.h>
+#include <asm/uaccess.h>
+#include <skas_ptrace.h>
@@ -162,48 +163,36 @@ static void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs,
* XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and
* PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check
*/
-void syscall_trace(struct uml_pt_regs *regs, int entryexit)
+void syscall_trace_enter(struct pt_regs *regs)
{
- int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit;
- int tracesysgood;
-
- if (!entryexit)
- audit_syscall_entry(HOST_AUDIT_ARCH,
- UPT_SYSCALL_NR(regs),
- UPT_SYSCALL_ARG1(regs),
- UPT_SYSCALL_ARG2(regs),
- UPT_SYSCALL_ARG3(regs),
- UPT_SYSCALL_ARG4(regs));
- else
- audit_syscall_exit(regs);
-
- /* Fake a debug trap */
- if (is_singlestep)
- send_sigtrap(current, regs, 0);
+ audit_syscall_entry(HOST_AUDIT_ARCH,
+ UPT_SYSCALL_NR(&regs->regs),
+ UPT_SYSCALL_ARG1(&regs->regs),
+ UPT_SYSCALL_ARG2(&regs->regs),
+ UPT_SYSCALL_ARG3(&regs->regs),
+ UPT_SYSCALL_ARG4(&regs->regs));
if (!test_thread_flag(TIF_SYSCALL_TRACE))
return;
- if (!(current->ptrace & PT_PTRACED))
- return;
+ tracehook_report_syscall_entry(regs);
+}
- /*
- * the 0x80 provides a way for the tracing parent to distinguish
- * between a syscall stop and SIGTRAP delivery
- */
- tracesysgood = (current->ptrace & PT_TRACESYSGOOD);
- ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0));
+void syscall_trace_leave(struct pt_regs *regs)
+{
+ int ptraced = current->ptrace;
- if (entryexit) /* force do_signal() --> is_syscall() */
- set_thread_flag(TIF_SIGPENDING);
+ audit_syscall_exit(regs);
- /*
- * this isn't the same as continuing with a signal, but it will do
- * for normal use. strace only continues with a signal if the
- * stopping signal is not SIGTRAP. -brl
- */
- if (current->exit_code) {
- send_sig(current->exit_code, current, 1);
- current->exit_code = 0;
- }
+ /* Fake a debug trap */
+ if (ptraced & PT_DTRACE)
+ send_sigtrap(current, &regs->regs, 0);
+
+ if (!test_thread_flag(TIF_SYSCALL_TRACE))
+ return;
+
+ tracehook_report_syscall_exit(regs, 0);
+ /* force do_signal() --> is_syscall() */
+ if (ptraced & PT_PTRACED)
+ set_thread_flag(TIF_SIGPENDING);
}
diff --git a/arch/um/kernel/sigio.c b/arch/um/kernel/sigio.c
index 2a163925576..c88211139a5 100644
--- a/arch/um/kernel/sigio.c
+++ b/arch/um/kernel/sigio.c
@@ -25,8 +25,7 @@ int write_sigio_irq(int fd)
int err;
err = um_request_irq(SIGIO_WRITE_IRQ, fd, IRQ_READ, sigio_interrupt,
- IRQF_SAMPLE_RANDOM, "write sigio",
- NULL);
+ 0, "write sigio", NULL);
if (err) {
printk(KERN_ERR "write_sigio_irq : um_request_irq failed, "
"err = %d\n", err);
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index 05fbeb480e0..86368a025a9 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -18,7 +18,7 @@ void handle_syscall(struct uml_pt_regs *r)
long result;
int syscall;
- syscall_trace(r, 0);
+ syscall_trace_enter(regs);
/*
* This should go in the declaration of syscall, but when I do that,
@@ -34,7 +34,7 @@ void handle_syscall(struct uml_pt_regs *r)
result = -ENOSYS;
else result = EXECUTE_SYSCALL(syscall, regs);
- UPT_SET_SYSCALL_RETURN(r, result);
+ PT_REGS_SET_SYSCALL_RETURN(regs, result);
- syscall_trace(r, 1);
+ syscall_trace_leave(regs);
}
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index d1a23fb3190..5f76d4ba151 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -13,7 +13,7 @@
#include "kern_util.h"
#include "os.h"
-void timer_handler(int sig, struct uml_pt_regs *regs)
+void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
{
unsigned long flags;
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index 3be60765c0e..0353b98ae35 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -172,7 +172,7 @@ void fatal_sigsegv(void)
os_dump_core();
}
-void segv_handler(int sig, struct uml_pt_regs *regs)
+void segv_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
{
struct faultinfo * fi = UPT_FAULTINFO(regs);
@@ -258,8 +258,11 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
return 0;
}
-void relay_signal(int sig, struct uml_pt_regs *regs)
+void relay_signal(int sig, struct siginfo *si, struct uml_pt_regs *regs)
{
+ struct faultinfo *fi;
+ struct siginfo clean_si;
+
if (!UPT_IS_USER(regs)) {
if (sig == SIGBUS)
printk(KERN_ERR "Bus error - the host /dev/shm or /tmp "
@@ -269,18 +272,40 @@ void relay_signal(int sig, struct uml_pt_regs *regs)
arch_examine_signal(sig, regs);
- current->thread.arch.faultinfo = *UPT_FAULTINFO(regs);
- force_sig(sig, current);
+ memset(&clean_si, 0, sizeof(clean_si));
+ clean_si.si_signo = si->si_signo;
+ clean_si.si_errno = si->si_errno;
+ clean_si.si_code = si->si_code;
+ switch (sig) {
+ case SIGILL:
+ case SIGFPE:
+ case SIGSEGV:
+ case SIGBUS:
+ case SIGTRAP:
+ fi = UPT_FAULTINFO(regs);
+ clean_si.si_addr = (void __user *) FAULT_ADDRESS(*fi);
+ current->thread.arch.faultinfo = *fi;
+#ifdef __ARCH_SI_TRAPNO
+ clean_si.si_trapno = si->si_trapno;
+#endif
+ break;
+ default:
+ printk(KERN_ERR "Attempted to relay unknown signal %d (si_code = %d)\n",
+ sig, si->si_code);
+ }
+
+ force_sig_info(sig, &clean_si, current);
}
-void bus_handler(int sig, struct uml_pt_regs *regs)
+void bus_handler(int sig, struct siginfo *si, struct uml_pt_regs *regs)
{
if (current->thread.fault_catcher != NULL)
UML_LONGJMP(current->thread.fault_catcher, 1);
- else relay_signal(sig, regs);
+ else
+ relay_signal(sig, si, regs);
}
-void winch(int sig, struct uml_pt_regs *regs)
+void winch(int sig, struct siginfo *unused_si, struct uml_pt_regs *regs)
{
do_IRQ(WINCH_IRQ, regs);
}
diff --git a/arch/um/os-Linux/internal.h b/arch/um/os-Linux/internal.h
index 2c3c3ecd8c0..0dc2c9f135f 100644
--- a/arch/um/os-Linux/internal.h
+++ b/arch/um/os-Linux/internal.h
@@ -1 +1 @@
-void alarm_handler(int, mcontext_t *);
+void alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc);
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index 2d22f1fcd8e..6366ce904b9 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -13,8 +13,9 @@
#include "kern_util.h"
#include "os.h"
#include "sysdep/mcontext.h"
+#include "internal.h"
-void (*sig_info[NSIG])(int, struct uml_pt_regs *) = {
+void (*sig_info[NSIG])(int, siginfo_t *, struct uml_pt_regs *) = {
[SIGTRAP] = relay_signal,
[SIGFPE] = relay_signal,
[SIGILL] = relay_signal,
@@ -24,7 +25,7 @@ void (*sig_info[NSIG])(int, struct uml_pt_regs *) = {
[SIGIO] = sigio_handler,
[SIGVTALRM] = timer_handler };
-static void sig_handler_common(int sig, mcontext_t *mc)
+static void sig_handler_common(int sig, siginfo_t *si, mcontext_t *mc)
{
struct uml_pt_regs r;
int save_errno = errno;
@@ -40,7 +41,7 @@ static void sig_handler_common(int sig, mcontext_t *mc)
if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM))
unblock_signals();
- (*sig_info[sig])(sig, &r);
+ (*sig_info[sig])(sig, si, &r);
errno = save_errno;
}
@@ -60,7 +61,7 @@ static void sig_handler_common(int sig, mcontext_t *mc)
static int signals_enabled;
static unsigned int signals_pending;
-void sig_handler(int sig, mcontext_t *mc)
+void sig_handler(int sig, siginfo_t *si, mcontext_t *mc)
{
int enabled;
@@ -72,7 +73,7 @@ void sig_handler(int sig, mcontext_t *mc)
block_signals();
- sig_handler_common(sig, mc);
+ sig_handler_common(sig, si, mc);
set_signals(enabled);
}
@@ -85,10 +86,10 @@ static void real_alarm_handler(mcontext_t *mc)
get_regs_from_mc(&regs, mc);
regs.is_user = 0;
unblock_signals();
- timer_handler(SIGVTALRM, &regs);
+ timer_handler(SIGVTALRM, NULL, &regs);
}
-void alarm_handler(int sig, mcontext_t *mc)
+void alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc)
{
int enabled;
@@ -119,7 +120,7 @@ void set_sigstack(void *sig_stack, int size)
panic("enabling signal stack failed, errno = %d\n", errno);
}
-static void (*handlers[_NSIG])(int sig, mcontext_t *mc) = {
+static void (*handlers[_NSIG])(int sig, siginfo_t *si, mcontext_t *mc) = {
[SIGSEGV] = sig_handler,
[SIGBUS] = sig_handler,
[SIGILL] = sig_handler,
@@ -132,7 +133,7 @@ static void (*handlers[_NSIG])(int sig, mcontext_t *mc) = {
};
-static void hard_handler(int sig, siginfo_t *info, void *p)
+static void hard_handler(int sig, siginfo_t *si, void *p)
{
struct ucontext *uc = p;
mcontext_t *mc = &uc->uc_mcontext;
@@ -161,7 +162,7 @@ static void hard_handler(int sig, siginfo_t *info, void *p)
while ((sig = ffs(pending)) != 0){
sig--;
pending &= ~(1 << sig);
- (*handlers[sig])(sig, mc);
+ (*handlers[sig])(sig, si, mc);
}
/*
@@ -273,9 +274,12 @@ void unblock_signals(void)
* Deal with SIGIO first because the alarm handler might
* schedule, leaving the pending SIGIO stranded until we come
* back here.
+ *
+ * SIGIO's handler doesn't use siginfo or mcontext,
+ * so they can be NULL.
*/
if (save_pending & SIGIO_MASK)
- sig_handler_common(SIGIO, NULL);
+ sig_handler_common(SIGIO, NULL, NULL);
if (save_pending & SIGVTALRM_MASK)
real_alarm_handler(NULL);
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index cd65727854e..d93bb40499f 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -346,6 +346,10 @@ void userspace(struct uml_pt_regs *regs)
int err, status, op, pid = userspace_pid[0];
/* To prevent races if using_sysemu changes under us.*/
int local_using_sysemu;
+ siginfo_t si;
+
+ /* Handle any immediate reschedules or signals */
+ interrupt_end();
if (getitimer(ITIMER_VIRTUAL, &timer))
printk(UM_KERN_ERR "Failed to get itimer, errno = %d\n", errno);
@@ -404,13 +408,17 @@ void userspace(struct uml_pt_regs *regs)
if (WIFSTOPPED(status)) {
int sig = WSTOPSIG(status);
+
+ ptrace(PTRACE_GETSIGINFO, pid, 0, &si);
+
switch (sig) {
case SIGSEGV:
if (PTRACE_FULL_FAULTINFO ||
!ptrace_faultinfo) {
get_skas_faultinfo(pid,
&regs->faultinfo);
- (*sig_info[SIGSEGV])(SIGSEGV, regs);
+ (*sig_info[SIGSEGV])(SIGSEGV, &si,
+ regs);
}
else handle_segv(pid, regs);
break;
@@ -418,14 +426,14 @@ void userspace(struct uml_pt_regs *regs)
handle_trap(pid, regs, local_using_sysemu);
break;
case SIGTRAP:
- relay_signal(SIGTRAP, regs);
+ relay_signal(SIGTRAP, &si, regs);
break;
case SIGVTALRM:
now = os_nsecs();
if (now < nsecs)
break;
block_signals();
- (*sig_info[sig])(sig, regs);
+ (*sig_info[sig])(sig, &si, regs);
unblock_signals();
nsecs = timer.it_value.tv_sec *
UM_NSEC_PER_SEC +
@@ -439,7 +447,7 @@ void userspace(struct uml_pt_regs *regs)
case SIGFPE:
case SIGWINCH:
block_signals();
- (*sig_info[sig])(sig, regs);
+ (*sig_info[sig])(sig, &si, regs);
unblock_signals();
break;
default:
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index 910499d76a6..f60238559af 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -87,7 +87,7 @@ static int after_sleep_interval(struct timespec *ts)
static void deliver_alarm(void)
{
- alarm_handler(SIGVTALRM, NULL);
+ alarm_handler(SIGVTALRM, NULL, NULL);
}
static unsigned long long sleep_time(unsigned long long nsecs)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index c70684f859e..ba2657c4921 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -70,6 +70,7 @@ config X86
select HAVE_ARCH_JUMP_LABEL
select HAVE_TEXT_POKE_SMP
select HAVE_GENERIC_HARDIRQS
+ select ARCH_HAS_ATOMIC64_DEC_IF_POSITIVE
select SPARSE_IRQ
select GENERIC_FIND_FIRST_BIT
select GENERIC_IRQ_PROBE
@@ -84,6 +85,7 @@ config X86
select GENERIC_IOMAP
select DCACHE_WORD_ACCESS
select GENERIC_SMP_IDLE_THREAD
+ select ARCH_WANT_IPC_PARSE_VERSION if X86_32
select HAVE_ARCH_SECCOMP_FILTER
select BUILDTIME_EXTABLE_SORT
select GENERIC_CMOS_UPDATE
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h
index c78f14a0df0..dab39350e51 100644
--- a/arch/x86/include/asm/perf_event.h
+++ b/arch/x86/include/asm/perf_event.h
@@ -234,7 +234,7 @@ extern struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr);
extern void perf_get_x86_pmu_capability(struct x86_pmu_capability *cap);
extern void perf_check_microcode(void);
#else
-static inline perf_guest_switch_msr *perf_guest_get_msrs(int *nr)
+static inline struct perf_guest_switch_msr *perf_guest_get_msrs(int *nr)
{
*nr = 0;
return NULL;
diff --git a/arch/x86/include/asm/unistd.h b/arch/x86/include/asm/unistd.h
index 4437001d8e3..0d9776e9e2d 100644
--- a/arch/x86/include/asm/unistd.h
+++ b/arch/x86/include/asm/unistd.h
@@ -15,7 +15,6 @@
# ifdef CONFIG_X86_32
# include <asm/unistd_32.h>
-# define __ARCH_WANT_IPC_PARSE_VERSION
# define __ARCH_WANT_STAT64
# define __ARCH_WANT_SYS_IPC
# define __ARCH_WANT_SYS_OLD_MMAP
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h
index a15df4be151..821d53b696d 100644
--- a/arch/x86/kernel/cpu/perf_event.h
+++ b/arch/x86/kernel/cpu/perf_event.h
@@ -374,7 +374,7 @@ struct x86_pmu {
/*
* Intel DebugStore bits
*/
- int bts :1,
+ unsigned int bts :1,
bts_active :1,
pebs :1,
pebs_active :1,
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c
index 7a8b9d0abca..382366977d4 100644
--- a/arch/x86/kernel/cpu/perf_event_intel.c
+++ b/arch/x86/kernel/cpu/perf_event_intel.c
@@ -138,6 +138,84 @@ static u64 intel_pmu_event_map(int hw_event)
return intel_perfmon_event_map[hw_event];
}
+#define SNB_DMND_DATA_RD (1ULL << 0)
+#define SNB_DMND_RFO (1ULL << 1)
+#define SNB_DMND_IFETCH (1ULL << 2)
+#define SNB_DMND_WB (1ULL << 3)
+#define SNB_PF_DATA_RD (1ULL << 4)
+#define SNB_PF_RFO (1ULL << 5)
+#define SNB_PF_IFETCH (1ULL << 6)
+#define SNB_LLC_DATA_RD (1ULL << 7)
+#define SNB_LLC_RFO (1ULL << 8)
+#define SNB_LLC_IFETCH (1ULL << 9)
+#define SNB_BUS_LOCKS (1ULL << 10)
+#define SNB_STRM_ST (1ULL << 11)
+#define SNB_OTHER (1ULL << 15)
+#define SNB_RESP_ANY (1ULL << 16)
+#define SNB_NO_SUPP (1ULL << 17)
+#define SNB_LLC_HITM (1ULL << 18)
+#define SNB_LLC_HITE (1ULL << 19)
+#define SNB_LLC_HITS (1ULL << 20)
+#define SNB_LLC_HITF (1ULL << 21)
+#define SNB_LOCAL (1ULL << 22)
+#define SNB_REMOTE (0xffULL << 23)
+#define SNB_SNP_NONE (1ULL << 31)
+#define SNB_SNP_NOT_NEEDED (1ULL << 32)
+#define SNB_SNP_MISS (1ULL << 33)
+#define SNB_NO_FWD (1ULL << 34)
+#define SNB_SNP_FWD (1ULL << 35)
+#define SNB_HITM (1ULL << 36)
+#define SNB_NON_DRAM (1ULL << 37)
+
+#define SNB_DMND_READ (SNB_DMND_DATA_RD|SNB_LLC_DATA_RD)
+#define SNB_DMND_WRITE (SNB_DMND_RFO|SNB_LLC_RFO)
+#define SNB_DMND_PREFETCH (SNB_PF_DATA_RD|SNB_PF_RFO)
+
+#define SNB_SNP_ANY (SNB_SNP_NONE|SNB_SNP_NOT_NEEDED| \
+ SNB_SNP_MISS|SNB_NO_FWD|SNB_SNP_FWD| \
+ SNB_HITM)
+
+#define SNB_DRAM_ANY (SNB_LOCAL|SNB_REMOTE|SNB_SNP_ANY)
+#define SNB_DRAM_REMOTE (SNB_REMOTE|SNB_SNP_ANY)
+
+#define SNB_L3_ACCESS SNB_RESP_ANY
+#define SNB_L3_MISS (SNB_DRAM_ANY|SNB_NON_DRAM)
+
+static __initconst const u64 snb_hw_cache_extra_regs
+ [PERF_COUNT_HW_CACHE_MAX]
+ [PERF_COUNT_HW_CACHE_OP_MAX]
+ [PERF_COUNT_HW_CACHE_RESULT_MAX] =
+{
+ [ C(LL ) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = SNB_DMND_READ|SNB_L3_ACCESS,
+ [ C(RESULT_MISS) ] = SNB_DMND_READ|SNB_L3_MISS,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = SNB_DMND_WRITE|SNB_L3_ACCESS,
+ [ C(RESULT_MISS) ] = SNB_DMND_WRITE|SNB_L3_MISS,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = SNB_DMND_PREFETCH|SNB_L3_ACCESS,
+ [ C(RESULT_MISS) ] = SNB_DMND_PREFETCH|SNB_L3_MISS,
+ },
+ },
+ [ C(NODE) ] = {
+ [ C(OP_READ) ] = {
+ [ C(RESULT_ACCESS) ] = SNB_DMND_READ|SNB_DRAM_ANY,
+ [ C(RESULT_MISS) ] = SNB_DMND_READ|SNB_DRAM_REMOTE,
+ },
+ [ C(OP_WRITE) ] = {
+ [ C(RESULT_ACCESS) ] = SNB_DMND_WRITE|SNB_DRAM_ANY,
+ [ C(RESULT_MISS) ] = SNB_DMND_WRITE|SNB_DRAM_REMOTE,
+ },
+ [ C(OP_PREFETCH) ] = {
+ [ C(RESULT_ACCESS) ] = SNB_DMND_PREFETCH|SNB_DRAM_ANY,
+ [ C(RESULT_MISS) ] = SNB_DMND_PREFETCH|SNB_DRAM_REMOTE,
+ },
+ },
+};
+
static __initconst const u64 snb_hw_cache_event_ids
[PERF_COUNT_HW_CACHE_MAX]
[PERF_COUNT_HW_CACHE_OP_MAX]
@@ -235,16 +313,16 @@ static __initconst const u64 snb_hw_cache_event_ids
},
[ C(NODE) ] = {
[ C(OP_READ) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ [ C(RESULT_MISS) ] = 0x01b7,
},
[ C(OP_WRITE) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ [ C(RESULT_MISS) ] = 0x01b7,
},
[ C(OP_PREFETCH) ] = {
- [ C(RESULT_ACCESS) ] = -1,
- [ C(RESULT_MISS) ] = -1,
+ [ C(RESULT_ACCESS) ] = 0x01b7,
+ [ C(RESULT_MISS) ] = 0x01b7,
},
},
@@ -1964,6 +2042,8 @@ __init int intel_pmu_init(void)
case 58: /* IvyBridge */
memcpy(hw_cache_event_ids, snb_hw_cache_event_ids,
sizeof(hw_cache_event_ids));
+ memcpy(hw_cache_extra_regs, snb_hw_cache_extra_regs,
+ sizeof(hw_cache_extra_regs));
intel_pmu_lbr_init_snb();
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
index 19faffc6088..7563fda9f03 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c
@@ -18,6 +18,7 @@ static struct event_constraint constraint_empty =
EVENT_CONSTRAINT(0, 0, 0);
DEFINE_UNCORE_FORMAT_ATTR(event, event, "config:0-7");
+DEFINE_UNCORE_FORMAT_ATTR(event_ext, event, "config:0-7,21");
DEFINE_UNCORE_FORMAT_ATTR(umask, umask, "config:8-15");
DEFINE_UNCORE_FORMAT_ATTR(edge, edge, "config:18");
DEFINE_UNCORE_FORMAT_ATTR(tid_en, tid_en, "config:19");
@@ -33,10 +34,81 @@ DEFINE_UNCORE_FORMAT_ATTR(filter_tid, filter_tid, "config1:0-4");
DEFINE_UNCORE_FORMAT_ATTR(filter_nid, filter_nid, "config1:10-17");
DEFINE_UNCORE_FORMAT_ATTR(filter_state, filter_state, "config1:18-22");
DEFINE_UNCORE_FORMAT_ATTR(filter_opc, filter_opc, "config1:23-31");
-DEFINE_UNCORE_FORMAT_ATTR(filter_brand0, filter_brand0, "config1:0-7");
-DEFINE_UNCORE_FORMAT_ATTR(filter_brand1, filter_brand1, "config1:8-15");
-DEFINE_UNCORE_FORMAT_ATTR(filter_brand2, filter_brand2, "config1:16-23");
-DEFINE_UNCORE_FORMAT_ATTR(filter_brand3, filter_brand3, "config1:24-31");
+DEFINE_UNCORE_FORMAT_ATTR(filter_band0, filter_band0, "config1:0-7");
+DEFINE_UNCORE_FORMAT_ATTR(filter_band1, filter_band1, "config1:8-15");
+DEFINE_UNCORE_FORMAT_ATTR(filter_band2, filter_band2, "config1:16-23");
+DEFINE_UNCORE_FORMAT_ATTR(filter_band3, filter_band3, "config1:24-31");
+
+static u64 uncore_msr_read_counter(struct intel_uncore_box *box, struct perf_event *event)
+{
+ u64 count;
+
+ rdmsrl(event->hw.event_base, count);
+
+ return count;
+}
+
+/*
+ * generic get constraint function for shared match/mask registers.
+ */
+static struct event_constraint *
+uncore_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct intel_uncore_extra_reg *er;
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
+ unsigned long flags;
+ bool ok = false;
+
+ /*
+ * reg->alloc can be set due to existing state, so for fake box we
+ * need to ignore this, otherwise we might fail to allocate proper
+ * fake state for this extra reg constraint.
+ */
+ if (reg1->idx == EXTRA_REG_NONE ||
+ (!uncore_box_is_fake(box) && reg1->alloc))
+ return NULL;
+
+ er = &box->shared_regs[reg1->idx];
+ raw_spin_lock_irqsave(&er->lock, flags);
+ if (!atomic_read(&er->ref) ||
+ (er->config1 == reg1->config && er->config2 == reg2->config)) {
+ atomic_inc(&er->ref);
+ er->config1 = reg1->config;
+ er->config2 = reg2->config;
+ ok = true;
+ }
+ raw_spin_unlock_irqrestore(&er->lock, flags);
+
+ if (ok) {
+ if (!uncore_box_is_fake(box))
+ reg1->alloc = 1;
+ return NULL;
+ }
+
+ return &constraint_empty;
+}
+
+static void uncore_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct intel_uncore_extra_reg *er;
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+
+ /*
+ * Only put constraint if extra reg was actually allocated. Also
+ * takes care of event which do not use an extra shared reg.
+ *
+ * Also, if this is a fake box we shouldn't touch any event state
+ * (reg->alloc) and we don't care about leaving inconsistent box
+ * state either since it will be thrown out.
+ */
+ if (uncore_box_is_fake(box) || !reg1->alloc)
+ return;
+
+ er = &box->shared_regs[reg1->idx];
+ atomic_dec(&er->ref);
+ reg1->alloc = 0;
+}
/* Sandy Bridge-EP uncore support */
static struct intel_uncore_type snbep_uncore_cbox;
@@ -64,18 +136,15 @@ static void snbep_uncore_pci_enable_box(struct intel_uncore_box *box)
pci_write_config_dword(pdev, box_ctl, config);
}
-static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box,
- struct perf_event *event)
+static void snbep_uncore_pci_enable_event(struct intel_uncore_box *box, struct perf_event *event)
{
struct pci_dev *pdev = box->pci_dev;
struct hw_perf_event *hwc = &event->hw;
- pci_write_config_dword(pdev, hwc->config_base, hwc->config |
- SNBEP_PMON_CTL_EN);
+ pci_write_config_dword(pdev, hwc->config_base, hwc->config | SNBEP_PMON_CTL_EN);
}
-static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box,
- struct perf_event *event)
+static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box, struct perf_event *event)
{
struct pci_dev *pdev = box->pci_dev;
struct hw_perf_event *hwc = &event->hw;
@@ -83,8 +152,7 @@ static void snbep_uncore_pci_disable_event(struct intel_uncore_box *box,
pci_write_config_dword(pdev, hwc->config_base, hwc->config);
}
-static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box,
- struct perf_event *event)
+static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box, struct perf_event *event)
{
struct pci_dev *pdev = box->pci_dev;
struct hw_perf_event *hwc = &event->hw;
@@ -92,14 +160,15 @@ static u64 snbep_uncore_pci_read_counter(struct intel_uncore_box *box,
pci_read_config_dword(pdev, hwc->event_base, (u32 *)&count);
pci_read_config_dword(pdev, hwc->event_base + 4, (u32 *)&count + 1);
+
return count;
}
static void snbep_uncore_pci_init_box(struct intel_uncore_box *box)
{
struct pci_dev *pdev = box->pci_dev;
- pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL,
- SNBEP_PMON_BOX_CTL_INT);
+
+ pci_write_config_dword(pdev, SNBEP_PCI_PMON_BOX_CTL, SNBEP_PMON_BOX_CTL_INT);
}
static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box)
@@ -112,7 +181,6 @@ static void snbep_uncore_msr_disable_box(struct intel_uncore_box *box)
rdmsrl(msr, config);
config |= SNBEP_PMON_BOX_CTL_FRZ;
wrmsrl(msr, config);
- return;
}
}
@@ -126,12 +194,10 @@ static void snbep_uncore_msr_enable_box(struct intel_uncore_box *box)
rdmsrl(msr, config);
config &= ~SNBEP_PMON_BOX_CTL_FRZ;
wrmsrl(msr, config);
- return;
}
}
-static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box,
- struct perf_event *event)
+static void snbep_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
@@ -150,68 +216,15 @@ static void snbep_uncore_msr_disable_event(struct intel_uncore_box *box,
wrmsrl(hwc->config_base, hwc->config);
}
-static u64 snbep_uncore_msr_read_counter(struct intel_uncore_box *box,
- struct perf_event *event)
-{
- struct hw_perf_event *hwc = &event->hw;
- u64 count;
-
- rdmsrl(hwc->event_base, count);
- return count;
-}
-
static void snbep_uncore_msr_init_box(struct intel_uncore_box *box)
{
unsigned msr = uncore_msr_box_ctl(box);
+
if (msr)
wrmsrl(msr, SNBEP_PMON_BOX_CTL_INT);
}
-static struct event_constraint *
-snbep_uncore_get_constraint(struct intel_uncore_box *box,
- struct perf_event *event)
-{
- struct intel_uncore_extra_reg *er;
- struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
- unsigned long flags;
- bool ok = false;
-
- if (reg1->idx == EXTRA_REG_NONE || (box->phys_id >= 0 && reg1->alloc))
- return NULL;
-
- er = &box->shared_regs[reg1->idx];
- raw_spin_lock_irqsave(&er->lock, flags);
- if (!atomic_read(&er->ref) || er->config1 == reg1->config) {
- atomic_inc(&er->ref);
- er->config1 = reg1->config;
- ok = true;
- }
- raw_spin_unlock_irqrestore(&er->lock, flags);
-
- if (ok) {
- if (box->phys_id >= 0)
- reg1->alloc = 1;
- return NULL;
- }
- return &constraint_empty;
-}
-
-static void snbep_uncore_put_constraint(struct intel_uncore_box *box,
- struct perf_event *event)
-{
- struct intel_uncore_extra_reg *er;
- struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
-
- if (box->phys_id < 0 || !reg1->alloc)
- return;
-
- er = &box->shared_regs[reg1->idx];
- atomic_dec(&er->ref);
- reg1->alloc = 0;
-}
-
-static int snbep_uncore_hw_config(struct intel_uncore_box *box,
- struct perf_event *event)
+static int snbep_uncore_hw_config(struct intel_uncore_box *box, struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
@@ -221,14 +234,16 @@ static int snbep_uncore_hw_config(struct intel_uncore_box *box,
SNBEP_CBO_MSR_OFFSET * box->pmu->pmu_idx;
reg1->config = event->attr.config1 &
SNBEP_CB0_MSR_PMON_BOX_FILTER_MASK;
- } else if (box->pmu->type == &snbep_uncore_pcu) {
- reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER;
- reg1->config = event->attr.config1 &
- SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK;
} else {
- return 0;
+ if (box->pmu->type == &snbep_uncore_pcu) {
+ reg1->reg = SNBEP_PCU_MSR_PMON_BOX_FILTER;
+ reg1->config = event->attr.config1 & SNBEP_PCU_MSR_PMON_BOX_FILTER_MASK;
+ } else {
+ return 0;
+ }
}
reg1->idx = 0;
+
return 0;
}
@@ -272,10 +287,19 @@ static struct attribute *snbep_uncore_pcu_formats_attr[] = {
&format_attr_thresh5.attr,
&format_attr_occ_invert.attr,
&format_attr_occ_edge.attr,
- &format_attr_filter_brand0.attr,
- &format_attr_filter_brand1.attr,
- &format_attr_filter_brand2.attr,
- &format_attr_filter_brand3.attr,
+ &format_attr_filter_band0.attr,
+ &format_attr_filter_band1.attr,
+ &format_attr_filter_band2.attr,
+ &format_attr_filter_band3.attr,
+ NULL,
+};
+
+static struct attribute *snbep_uncore_qpi_formats_attr[] = {
+ &format_attr_event_ext.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh8.attr,
NULL,
};
@@ -314,15 +338,20 @@ static struct attribute_group snbep_uncore_pcu_format_group = {
.attrs = snbep_uncore_pcu_formats_attr,
};
+static struct attribute_group snbep_uncore_qpi_format_group = {
+ .name = "format",
+ .attrs = snbep_uncore_qpi_formats_attr,
+};
+
static struct intel_uncore_ops snbep_uncore_msr_ops = {
.init_box = snbep_uncore_msr_init_box,
.disable_box = snbep_uncore_msr_disable_box,
.enable_box = snbep_uncore_msr_enable_box,
.disable_event = snbep_uncore_msr_disable_event,
.enable_event = snbep_uncore_msr_enable_event,
- .read_counter = snbep_uncore_msr_read_counter,
- .get_constraint = snbep_uncore_get_constraint,
- .put_constraint = snbep_uncore_put_constraint,
+ .read_counter = uncore_msr_read_counter,
+ .get_constraint = uncore_get_constraint,
+ .put_constraint = uncore_put_constraint,
.hw_config = snbep_uncore_hw_config,
};
@@ -485,8 +514,13 @@ static struct intel_uncore_type snbep_uncore_qpi = {
.num_counters = 4,
.num_boxes = 2,
.perf_ctr_bits = 48,
+ .perf_ctr = SNBEP_PCI_PMON_CTR0,
+ .event_ctl = SNBEP_PCI_PMON_CTL0,
+ .event_mask = SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK,
+ .box_ctl = SNBEP_PCI_PMON_BOX_CTL,
+ .ops = &snbep_uncore_pci_ops,
.event_descs = snbep_uncore_qpi_events,
- SNBEP_UNCORE_PCI_COMMON_INIT(),
+ .format_group = &snbep_uncore_qpi_format_group,
};
@@ -603,10 +637,8 @@ static void snbep_pci2phy_map_init(void)
}
/* end of Sandy Bridge-EP uncore support */
-
/* Sandy Bridge uncore support */
-static void snb_uncore_msr_enable_event(struct intel_uncore_box *box,
- struct perf_event *event)
+static void snb_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
@@ -616,20 +648,11 @@ static void snb_uncore_msr_enable_event(struct intel_uncore_box *box,
wrmsrl(hwc->config_base, SNB_UNC_CTL_EN);
}
-static void snb_uncore_msr_disable_event(struct intel_uncore_box *box,
- struct perf_event *event)
+static void snb_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event)
{
wrmsrl(event->hw.config_base, 0);
}
-static u64 snb_uncore_msr_read_counter(struct intel_uncore_box *box,
- struct perf_event *event)
-{
- u64 count;
- rdmsrl(event->hw.event_base, count);
- return count;
-}
-
static void snb_uncore_msr_init_box(struct intel_uncore_box *box)
{
if (box->pmu->pmu_idx == 0) {
@@ -648,15 +671,15 @@ static struct attribute *snb_uncore_formats_attr[] = {
};
static struct attribute_group snb_uncore_format_group = {
- .name = "format",
- .attrs = snb_uncore_formats_attr,
+ .name = "format",
+ .attrs = snb_uncore_formats_attr,
};
static struct intel_uncore_ops snb_uncore_msr_ops = {
.init_box = snb_uncore_msr_init_box,
.disable_event = snb_uncore_msr_disable_event,
.enable_event = snb_uncore_msr_enable_event,
- .read_counter = snb_uncore_msr_read_counter,
+ .read_counter = uncore_msr_read_counter,
};
static struct event_constraint snb_uncore_cbox_constraints[] = {
@@ -697,12 +720,10 @@ static void nhm_uncore_msr_disable_box(struct intel_uncore_box *box)
static void nhm_uncore_msr_enable_box(struct intel_uncore_box *box)
{
- wrmsrl(NHM_UNC_PERF_GLOBAL_CTL,
- NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC);
+ wrmsrl(NHM_UNC_PERF_GLOBAL_CTL, NHM_UNC_GLOBAL_CTL_EN_PC_ALL | NHM_UNC_GLOBAL_CTL_EN_FC);
}
-static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box,
- struct perf_event *event)
+static void nhm_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
@@ -744,7 +765,7 @@ static struct intel_uncore_ops nhm_uncore_msr_ops = {
.enable_box = nhm_uncore_msr_enable_box,
.disable_event = snb_uncore_msr_disable_event,
.enable_event = nhm_uncore_msr_enable_event,
- .read_counter = snb_uncore_msr_read_counter,
+ .read_counter = uncore_msr_read_counter,
};
static struct intel_uncore_type nhm_uncore = {
@@ -769,8 +790,1041 @@ static struct intel_uncore_type *nhm_msr_uncores[] = {
};
/* end of Nehalem uncore support */
-static void uncore_assign_hw_event(struct intel_uncore_box *box,
- struct perf_event *event, int idx)
+/* Nehalem-EX uncore support */
+#define __BITS_VALUE(x, i, n) ((typeof(x))(((x) >> ((i) * (n))) & \
+ ((1ULL << (n)) - 1)))
+
+DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5");
+DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7");
+DEFINE_UNCORE_FORMAT_ATTR(mm_cfg, mm_cfg, "config:63");
+DEFINE_UNCORE_FORMAT_ATTR(match, match, "config1:0-63");
+DEFINE_UNCORE_FORMAT_ATTR(mask, mask, "config2:0-63");
+
+static void nhmex_uncore_msr_init_box(struct intel_uncore_box *box)
+{
+ wrmsrl(NHMEX_U_MSR_PMON_GLOBAL_CTL, NHMEX_U_PMON_GLOBAL_EN_ALL);
+}
+
+static void nhmex_uncore_msr_disable_box(struct intel_uncore_box *box)
+{
+ unsigned msr = uncore_msr_box_ctl(box);
+ u64 config;
+
+ if (msr) {
+ rdmsrl(msr, config);
+ config &= ~((1ULL << uncore_num_counters(box)) - 1);
+ /* WBox has a fixed counter */
+ if (uncore_msr_fixed_ctl(box))
+ config &= ~NHMEX_W_PMON_GLOBAL_FIXED_EN;
+ wrmsrl(msr, config);
+ }
+}
+
+static void nhmex_uncore_msr_enable_box(struct intel_uncore_box *box)
+{
+ unsigned msr = uncore_msr_box_ctl(box);
+ u64 config;
+
+ if (msr) {
+ rdmsrl(msr, config);
+ config |= (1ULL << uncore_num_counters(box)) - 1;
+ /* WBox has a fixed counter */
+ if (uncore_msr_fixed_ctl(box))
+ config |= NHMEX_W_PMON_GLOBAL_FIXED_EN;
+ wrmsrl(msr, config);
+ }
+}
+
+static void nhmex_uncore_msr_disable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ wrmsrl(event->hw.config_base, 0);
+}
+
+static void nhmex_uncore_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+
+ if (hwc->idx >= UNCORE_PMC_IDX_FIXED)
+ wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0);
+ else if (box->pmu->type->event_mask & NHMEX_PMON_CTL_EN_BIT0)
+ wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22);
+ else
+ wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0);
+}
+
+#define NHMEX_UNCORE_OPS_COMMON_INIT() \
+ .init_box = nhmex_uncore_msr_init_box, \
+ .disable_box = nhmex_uncore_msr_disable_box, \
+ .enable_box = nhmex_uncore_msr_enable_box, \
+ .disable_event = nhmex_uncore_msr_disable_event, \
+ .read_counter = uncore_msr_read_counter
+
+static struct intel_uncore_ops nhmex_uncore_ops = {
+ NHMEX_UNCORE_OPS_COMMON_INIT(),
+ .enable_event = nhmex_uncore_msr_enable_event,
+};
+
+static struct attribute *nhmex_uncore_ubox_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_edge.attr,
+ NULL,
+};
+
+static struct attribute_group nhmex_uncore_ubox_format_group = {
+ .name = "format",
+ .attrs = nhmex_uncore_ubox_formats_attr,
+};
+
+static struct intel_uncore_type nhmex_uncore_ubox = {
+ .name = "ubox",
+ .num_counters = 1,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .event_ctl = NHMEX_U_MSR_PMON_EV_SEL,
+ .perf_ctr = NHMEX_U_MSR_PMON_CTR,
+ .event_mask = NHMEX_U_PMON_RAW_EVENT_MASK,
+ .box_ctl = NHMEX_U_MSR_PMON_GLOBAL_CTL,
+ .ops = &nhmex_uncore_ops,
+ .format_group = &nhmex_uncore_ubox_format_group
+};
+
+static struct attribute *nhmex_uncore_cbox_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh8.attr,
+ NULL,
+};
+
+static struct attribute_group nhmex_uncore_cbox_format_group = {
+ .name = "format",
+ .attrs = nhmex_uncore_cbox_formats_attr,
+};
+
+static struct intel_uncore_type nhmex_uncore_cbox = {
+ .name = "cbox",
+ .num_counters = 6,
+ .num_boxes = 8,
+ .perf_ctr_bits = 48,
+ .event_ctl = NHMEX_C0_MSR_PMON_EV_SEL0,
+ .perf_ctr = NHMEX_C0_MSR_PMON_CTR0,
+ .event_mask = NHMEX_PMON_RAW_EVENT_MASK,
+ .box_ctl = NHMEX_C0_MSR_PMON_GLOBAL_CTL,
+ .msr_offset = NHMEX_C_MSR_OFFSET,
+ .pair_ctr_ctl = 1,
+ .ops = &nhmex_uncore_ops,
+ .format_group = &nhmex_uncore_cbox_format_group
+};
+
+static struct uncore_event_desc nhmex_uncore_wbox_events[] = {
+ INTEL_UNCORE_EVENT_DESC(clockticks, "event=0xff,umask=0"),
+ { /* end: all zeroes */ },
+};
+
+static struct intel_uncore_type nhmex_uncore_wbox = {
+ .name = "wbox",
+ .num_counters = 4,
+ .num_boxes = 1,
+ .perf_ctr_bits = 48,
+ .event_ctl = NHMEX_W_MSR_PMON_CNT0,
+ .perf_ctr = NHMEX_W_MSR_PMON_EVT_SEL0,
+ .fixed_ctr = NHMEX_W_MSR_PMON_FIXED_CTR,
+ .fixed_ctl = NHMEX_W_MSR_PMON_FIXED_CTL,
+ .event_mask = NHMEX_PMON_RAW_EVENT_MASK,
+ .box_ctl = NHMEX_W_MSR_GLOBAL_CTL,
+ .pair_ctr_ctl = 1,
+ .event_descs = nhmex_uncore_wbox_events,
+ .ops = &nhmex_uncore_ops,
+ .format_group = &nhmex_uncore_cbox_format_group
+};
+
+static int nhmex_bbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+ int ctr, ev_sel;
+
+ ctr = (hwc->config & NHMEX_B_PMON_CTR_MASK) >>
+ NHMEX_B_PMON_CTR_SHIFT;
+ ev_sel = (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK) >>
+ NHMEX_B_PMON_CTL_EV_SEL_SHIFT;
+
+ /* events that do not use the match/mask registers */
+ if ((ctr == 0 && ev_sel > 0x3) || (ctr == 1 && ev_sel > 0x6) ||
+ (ctr == 2 && ev_sel != 0x4) || ctr == 3)
+ return 0;
+
+ if (box->pmu->pmu_idx == 0)
+ reg1->reg = NHMEX_B0_MSR_MATCH;
+ else
+ reg1->reg = NHMEX_B1_MSR_MATCH;
+ reg1->idx = 0;
+ reg1->config = event->attr.config1;
+ reg2->config = event->attr.config2;
+ return 0;
+}
+
+static void nhmex_bbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+
+ if (reg1->idx != EXTRA_REG_NONE) {
+ wrmsrl(reg1->reg, reg1->config);
+ wrmsrl(reg1->reg + 1, reg2->config);
+ }
+ wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 |
+ (hwc->config & NHMEX_B_PMON_CTL_EV_SEL_MASK));
+}
+
+/*
+ * The Bbox has 4 counters, but each counter monitors different events.
+ * Use bits 6-7 in the event config to select counter.
+ */
+static struct event_constraint nhmex_uncore_bbox_constraints[] = {
+ EVENT_CONSTRAINT(0 , 1, 0xc0),
+ EVENT_CONSTRAINT(0x40, 2, 0xc0),
+ EVENT_CONSTRAINT(0x80, 4, 0xc0),
+ EVENT_CONSTRAINT(0xc0, 8, 0xc0),
+ EVENT_CONSTRAINT_END,
+};
+
+static struct attribute *nhmex_uncore_bbox_formats_attr[] = {
+ &format_attr_event5.attr,
+ &format_attr_counter.attr,
+ &format_attr_match.attr,
+ &format_attr_mask.attr,
+ NULL,
+};
+
+static struct attribute_group nhmex_uncore_bbox_format_group = {
+ .name = "format",
+ .attrs = nhmex_uncore_bbox_formats_attr,
+};
+
+static struct intel_uncore_ops nhmex_uncore_bbox_ops = {
+ NHMEX_UNCORE_OPS_COMMON_INIT(),
+ .enable_event = nhmex_bbox_msr_enable_event,
+ .hw_config = nhmex_bbox_hw_config,
+ .get_constraint = uncore_get_constraint,
+ .put_constraint = uncore_put_constraint,
+};
+
+static struct intel_uncore_type nhmex_uncore_bbox = {
+ .name = "bbox",
+ .num_counters = 4,
+ .num_boxes = 2,
+ .perf_ctr_bits = 48,
+ .event_ctl = NHMEX_B0_MSR_PMON_CTL0,
+ .perf_ctr = NHMEX_B0_MSR_PMON_CTR0,
+ .event_mask = NHMEX_B_PMON_RAW_EVENT_MASK,
+ .box_ctl = NHMEX_B0_MSR_PMON_GLOBAL_CTL,
+ .msr_offset = NHMEX_B_MSR_OFFSET,
+ .pair_ctr_ctl = 1,
+ .num_shared_regs = 1,
+ .constraints = nhmex_uncore_bbox_constraints,
+ .ops = &nhmex_uncore_bbox_ops,
+ .format_group = &nhmex_uncore_bbox_format_group
+};
+
+static int nhmex_sbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
+
+ if (event->attr.config & NHMEX_S_PMON_MM_CFG_EN) {
+ reg1->config = event->attr.config1;
+ reg2->config = event->attr.config2;
+ } else {
+ reg1->config = ~0ULL;
+ reg2->config = ~0ULL;
+ }
+
+ if (box->pmu->pmu_idx == 0)
+ reg1->reg = NHMEX_S0_MSR_MM_CFG;
+ else
+ reg1->reg = NHMEX_S1_MSR_MM_CFG;
+
+ reg1->idx = 0;
+
+ return 0;
+}
+
+static void nhmex_sbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+
+ wrmsrl(reg1->reg, 0);
+ if (reg1->config != ~0ULL || reg2->config != ~0ULL) {
+ wrmsrl(reg1->reg + 1, reg1->config);
+ wrmsrl(reg1->reg + 2, reg2->config);
+ wrmsrl(reg1->reg, NHMEX_S_PMON_MM_CFG_EN);
+ }
+ wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT22);
+}
+
+static struct attribute *nhmex_uncore_sbox_formats_attr[] = {
+ &format_attr_event.attr,
+ &format_attr_umask.attr,
+ &format_attr_edge.attr,
+ &format_attr_inv.attr,
+ &format_attr_thresh8.attr,
+ &format_attr_mm_cfg.attr,
+ &format_attr_match.attr,
+ &format_attr_mask.attr,
+ NULL,
+};
+
+static struct attribute_group nhmex_uncore_sbox_format_group = {
+ .name = "format",
+ .attrs = nhmex_uncore_sbox_formats_attr,
+};
+
+static struct intel_uncore_ops nhmex_uncore_sbox_ops = {
+ NHMEX_UNCORE_OPS_COMMON_INIT(),
+ .enable_event = nhmex_sbox_msr_enable_event,
+ .hw_config = nhmex_sbox_hw_config,
+ .get_constraint = uncore_get_constraint,
+ .put_constraint = uncore_put_constraint,
+};
+
+static struct intel_uncore_type nhmex_uncore_sbox = {
+ .name = "sbox",
+ .num_counters = 4,
+ .num_boxes = 2,
+ .perf_ctr_bits = 48,
+ .event_ctl = NHMEX_S0_MSR_PMON_CTL0,
+ .perf_ctr = NHMEX_S0_MSR_PMON_CTR0,
+ .event_mask = NHMEX_PMON_RAW_EVENT_MASK,
+ .box_ctl = NHMEX_S0_MSR_PMON_GLOBAL_CTL,
+ .msr_offset = NHMEX_S_MSR_OFFSET,
+ .pair_ctr_ctl = 1,
+ .num_shared_regs = 1,
+ .ops = &nhmex_uncore_sbox_ops,
+ .format_group = &nhmex_uncore_sbox_format_group
+};
+
+enum {
+ EXTRA_REG_NHMEX_M_FILTER,
+ EXTRA_REG_NHMEX_M_DSP,
+ EXTRA_REG_NHMEX_M_ISS,
+ EXTRA_REG_NHMEX_M_MAP,
+ EXTRA_REG_NHMEX_M_MSC_THR,
+ EXTRA_REG_NHMEX_M_PGT,
+ EXTRA_REG_NHMEX_M_PLD,
+ EXTRA_REG_NHMEX_M_ZDP_CTL_FVC,
+};
+
+static struct extra_reg nhmex_uncore_mbox_extra_regs[] = {
+ MBOX_INC_SEL_EXTAR_REG(0x0, DSP),
+ MBOX_INC_SEL_EXTAR_REG(0x4, MSC_THR),
+ MBOX_INC_SEL_EXTAR_REG(0x5, MSC_THR),
+ MBOX_INC_SEL_EXTAR_REG(0x9, ISS),
+ /* event 0xa uses two extra registers */
+ MBOX_INC_SEL_EXTAR_REG(0xa, ISS),
+ MBOX_INC_SEL_EXTAR_REG(0xa, PLD),
+ MBOX_INC_SEL_EXTAR_REG(0xb, PLD),
+ /* events 0xd ~ 0x10 use the same extra register */
+ MBOX_INC_SEL_EXTAR_REG(0xd, ZDP_CTL_FVC),
+ MBOX_INC_SEL_EXTAR_REG(0xe, ZDP_CTL_FVC),
+ MBOX_INC_SEL_EXTAR_REG(0xf, ZDP_CTL_FVC),
+ MBOX_INC_SEL_EXTAR_REG(0x10, ZDP_CTL_FVC),
+ MBOX_INC_SEL_EXTAR_REG(0x16, PGT),
+ MBOX_SET_FLAG_SEL_EXTRA_REG(0x0, DSP),
+ MBOX_SET_FLAG_SEL_EXTRA_REG(0x1, ISS),
+ MBOX_SET_FLAG_SEL_EXTRA_REG(0x5, PGT),
+ MBOX_SET_FLAG_SEL_EXTRA_REG(0x6, MAP),
+ EVENT_EXTRA_END
+};
+
+static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config)
+{
+ struct intel_uncore_extra_reg *er;
+ unsigned long flags;
+ bool ret = false;
+ u64 mask;
+
+ if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
+ er = &box->shared_regs[idx];
+ raw_spin_lock_irqsave(&er->lock, flags);
+ if (!atomic_read(&er->ref) || er->config == config) {
+ atomic_inc(&er->ref);
+ er->config = config;
+ ret = true;
+ }
+ raw_spin_unlock_irqrestore(&er->lock, flags);
+
+ return ret;
+ }
+ /*
+ * The ZDP_CTL_FVC MSR has 4 fields which are used to control
+ * events 0xd ~ 0x10. Besides these 4 fields, there are additional
+ * fields which are shared.
+ */
+ idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
+ if (WARN_ON_ONCE(idx >= 4))
+ return false;
+
+ /* mask of the shared fields */
+ mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK;
+ er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
+
+ raw_spin_lock_irqsave(&er->lock, flags);
+ /* add mask of the non-shared field if it's in use */
+ if (__BITS_VALUE(atomic_read(&er->ref), idx, 8))
+ mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+
+ if (!atomic_read(&er->ref) || !((er->config ^ config) & mask)) {
+ atomic_add(1 << (idx * 8), &er->ref);
+ mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK |
+ NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+ er->config &= ~mask;
+ er->config |= (config & mask);
+ ret = true;
+ }
+ raw_spin_unlock_irqrestore(&er->lock, flags);
+
+ return ret;
+}
+
+static void nhmex_mbox_put_shared_reg(struct intel_uncore_box *box, int idx)
+{
+ struct intel_uncore_extra_reg *er;
+
+ if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
+ er = &box->shared_regs[idx];
+ atomic_dec(&er->ref);
+ return;
+ }
+
+ idx -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
+ er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
+ atomic_sub(1 << (idx * 8), &er->ref);
+}
+
+u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ int idx, orig_idx = __BITS_VALUE(reg1->idx, 0, 8);
+ u64 config = reg1->config;
+
+ /* get the non-shared control bits and shift them */
+ idx = orig_idx - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
+ config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx);
+ if (new_idx > orig_idx) {
+ idx = new_idx - orig_idx;
+ config <<= 3 * idx;
+ } else {
+ idx = orig_idx - new_idx;
+ config >>= 3 * idx;
+ }
+
+ /* add the shared control bits back */
+ config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config;
+ if (modify) {
+ /* adjust the main event selector */
+ if (new_idx > orig_idx)
+ hwc->config += idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT;
+ else
+ hwc->config -= idx << NHMEX_M_PMON_CTL_INC_SEL_SHIFT;
+ reg1->config = config;
+ reg1->idx = ~0xff | new_idx;
+ }
+ return config;
+}
+
+static struct event_constraint *
+nhmex_mbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
+ int i, idx[2], alloc = 0;
+ u64 config1 = reg1->config;
+
+ idx[0] = __BITS_VALUE(reg1->idx, 0, 8);
+ idx[1] = __BITS_VALUE(reg1->idx, 1, 8);
+again:
+ for (i = 0; i < 2; i++) {
+ if (!uncore_box_is_fake(box) && (reg1->alloc & (0x1 << i)))
+ idx[i] = 0xff;
+
+ if (idx[i] == 0xff)
+ continue;
+
+ if (!nhmex_mbox_get_shared_reg(box, idx[i],
+ __BITS_VALUE(config1, i, 32)))
+ goto fail;
+ alloc |= (0x1 << i);
+ }
+
+ /* for the match/mask registers */
+ if ((uncore_box_is_fake(box) || !reg2->alloc) &&
+ !nhmex_mbox_get_shared_reg(box, reg2->idx, reg2->config))
+ goto fail;
+
+ /*
+ * If it's a fake box -- as per validate_{group,event}() we
+ * shouldn't touch event state and we can avoid doing so
+ * since both will only call get_event_constraints() once
+ * on each event, this avoids the need for reg->alloc.
+ */
+ if (!uncore_box_is_fake(box)) {
+ if (idx[0] != 0xff && idx[0] != __BITS_VALUE(reg1->idx, 0, 8))
+ nhmex_mbox_alter_er(event, idx[0], true);
+ reg1->alloc |= alloc;
+ reg2->alloc = 1;
+ }
+ return NULL;
+fail:
+ if (idx[0] != 0xff && !(alloc & 0x1) &&
+ idx[0] >= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC) {
+ /*
+ * events 0xd ~ 0x10 are functional identical, but are
+ * controlled by different fields in the ZDP_CTL_FVC
+ * register. If we failed to take one field, try the
+ * rest 3 choices.
+ */
+ BUG_ON(__BITS_VALUE(reg1->idx, 1, 8) != 0xff);
+ idx[0] -= EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
+ idx[0] = (idx[0] + 1) % 4;
+ idx[0] += EXTRA_REG_NHMEX_M_ZDP_CTL_FVC;
+ if (idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) {
+ config1 = nhmex_mbox_alter_er(event, idx[0], false);
+ goto again;
+ }
+ }
+
+ if (alloc & 0x1)
+ nhmex_mbox_put_shared_reg(box, idx[0]);
+ if (alloc & 0x2)
+ nhmex_mbox_put_shared_reg(box, idx[1]);
+ return &constraint_empty;
+}
+
+static void nhmex_mbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
+
+ if (uncore_box_is_fake(box))
+ return;
+
+ if (reg1->alloc & 0x1)
+ nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 0, 8));
+ if (reg1->alloc & 0x2)
+ nhmex_mbox_put_shared_reg(box, __BITS_VALUE(reg1->idx, 1, 8));
+ reg1->alloc = 0;
+
+ if (reg2->alloc) {
+ nhmex_mbox_put_shared_reg(box, reg2->idx);
+ reg2->alloc = 0;
+ }
+}
+
+static int nhmex_mbox_extra_reg_idx(struct extra_reg *er)
+{
+ if (er->idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC)
+ return er->idx;
+ return er->idx + (er->event >> NHMEX_M_PMON_CTL_INC_SEL_SHIFT) - 0xd;
+}
+
+static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct intel_uncore_type *type = box->pmu->type;
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
+ struct extra_reg *er;
+ unsigned msr;
+ int reg_idx = 0;
+
+ if (WARN_ON_ONCE(reg1->idx != -1))
+ return -EINVAL;
+ /*
+ * The mbox events may require 2 extra MSRs at the most. But only
+ * the lower 32 bits in these MSRs are significant, so we can use
+ * config1 to pass two MSRs' config.
+ */
+ for (er = nhmex_uncore_mbox_extra_regs; er->msr; er++) {
+ if (er->event != (event->hw.config & er->config_mask))
+ continue;
+ if (event->attr.config1 & ~er->valid_mask)
+ return -EINVAL;
+ if (er->idx == __BITS_VALUE(reg1->idx, 0, 8) ||
+ er->idx == __BITS_VALUE(reg1->idx, 1, 8))
+ continue;
+ if (WARN_ON_ONCE(reg_idx >= 2))
+ return -EINVAL;
+
+ msr = er->msr + type->msr_offset * box->pmu->pmu_idx;
+ if (WARN_ON_ONCE(msr >= 0xffff || er->idx >= 0xff))
+ return -EINVAL;
+
+ /* always use the 32~63 bits to pass the PLD config */
+ if (er->idx == EXTRA_REG_NHMEX_M_PLD)
+ reg_idx = 1;
+
+ reg1->idx &= ~(0xff << (reg_idx * 8));
+ reg1->reg &= ~(0xffff << (reg_idx * 16));
+ reg1->idx |= nhmex_mbox_extra_reg_idx(er) << (reg_idx * 8);
+ reg1->reg |= msr << (reg_idx * 16);
+ reg1->config = event->attr.config1;
+ reg_idx++;
+ }
+ /* use config2 to pass the filter config */
+ reg2->idx = EXTRA_REG_NHMEX_M_FILTER;
+ if (event->attr.config2 & NHMEX_M_PMON_MM_CFG_EN)
+ reg2->config = event->attr.config2;
+ else
+ reg2->config = ~0ULL;
+ if (box->pmu->pmu_idx == 0)
+ reg2->reg = NHMEX_M0_MSR_PMU_MM_CFG;
+ else
+ reg2->reg = NHMEX_M1_MSR_PMU_MM_CFG;
+
+ return 0;
+}
+
+static u64 nhmex_mbox_shared_reg_config(struct intel_uncore_box *box, int idx)
+{
+ struct intel_uncore_extra_reg *er;
+ unsigned long flags;
+ u64 config;
+
+ if (idx < EXTRA_REG_NHMEX_M_ZDP_CTL_FVC)
+ return box->shared_regs[idx].config;
+
+ er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC];
+ raw_spin_lock_irqsave(&er->lock, flags);
+ config = er->config;
+ raw_spin_unlock_irqrestore(&er->lock, flags);
+ return config;
+}
+
+static void nhmex_mbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+ int idx;
+
+ idx = __BITS_VALUE(reg1->idx, 0, 8);
+ if (idx != 0xff)
+ wrmsrl(__BITS_VALUE(reg1->reg, 0, 16),
+ nhmex_mbox_shared_reg_config(box, idx));
+ idx = __BITS_VALUE(reg1->idx, 1, 8);
+ if (idx != 0xff)
+ wrmsrl(__BITS_VALUE(reg1->reg, 1, 16),
+ nhmex_mbox_shared_reg_config(box, idx));
+
+ wrmsrl(reg2->reg, 0);
+ if (reg2->config != ~0ULL) {
+ wrmsrl(reg2->reg + 1,
+ reg2->config & NHMEX_M_PMON_ADDR_MATCH_MASK);
+ wrmsrl(reg2->reg + 2, NHMEX_M_PMON_ADDR_MASK_MASK &
+ (reg2->config >> NHMEX_M_PMON_ADDR_MASK_SHIFT));
+ wrmsrl(reg2->reg, NHMEX_M_PMON_MM_CFG_EN);
+ }
+
+ wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0);
+}
+
+DEFINE_UNCORE_FORMAT_ATTR(count_mode, count_mode, "config:2-3");
+DEFINE_UNCORE_FORMAT_ATTR(storage_mode, storage_mode, "config:4-5");
+DEFINE_UNCORE_FORMAT_ATTR(wrap_mode, wrap_mode, "config:6");
+DEFINE_UNCORE_FORMAT_ATTR(flag_mode, flag_mode, "config:7");
+DEFINE_UNCORE_FORMAT_ATTR(inc_sel, inc_sel, "config:9-13");
+DEFINE_UNCORE_FORMAT_ATTR(set_flag_sel, set_flag_sel, "config:19-21");
+DEFINE_UNCORE_FORMAT_ATTR(filter_cfg, filter_cfg, "config2:63");
+DEFINE_UNCORE_FORMAT_ATTR(filter_match, filter_match, "config2:0-33");
+DEFINE_UNCORE_FORMAT_ATTR(filter_mask, filter_mask, "config2:34-61");
+DEFINE_UNCORE_FORMAT_ATTR(dsp, dsp, "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(thr, thr, "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(fvc, fvc, "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(pgt, pgt, "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(map, map, "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(iss, iss, "config1:0-31");
+DEFINE_UNCORE_FORMAT_ATTR(pld, pld, "config1:32-63");
+
+static struct attribute *nhmex_uncore_mbox_formats_attr[] = {
+ &format_attr_count_mode.attr,
+ &format_attr_storage_mode.attr,
+ &format_attr_wrap_mode.attr,
+ &format_attr_flag_mode.attr,
+ &format_attr_inc_sel.attr,
+ &format_attr_set_flag_sel.attr,
+ &format_attr_filter_cfg.attr,
+ &format_attr_filter_match.attr,
+ &format_attr_filter_mask.attr,
+ &format_attr_dsp.attr,
+ &format_attr_thr.attr,
+ &format_attr_fvc.attr,
+ &format_attr_pgt.attr,
+ &format_attr_map.attr,
+ &format_attr_iss.attr,
+ &format_attr_pld.attr,
+ NULL,
+};
+
+static struct attribute_group nhmex_uncore_mbox_format_group = {
+ .name = "format",
+ .attrs = nhmex_uncore_mbox_formats_attr,
+};
+
+static struct uncore_event_desc nhmex_uncore_mbox_events[] = {
+ INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x2800"),
+ INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x2820"),
+ { /* end: all zeroes */ },
+};
+
+static struct intel_uncore_ops nhmex_uncore_mbox_ops = {
+ NHMEX_UNCORE_OPS_COMMON_INIT(),
+ .enable_event = nhmex_mbox_msr_enable_event,
+ .hw_config = nhmex_mbox_hw_config,
+ .get_constraint = nhmex_mbox_get_constraint,
+ .put_constraint = nhmex_mbox_put_constraint,
+};
+
+static struct intel_uncore_type nhmex_uncore_mbox = {
+ .name = "mbox",
+ .num_counters = 6,
+ .num_boxes = 2,
+ .perf_ctr_bits = 48,
+ .event_ctl = NHMEX_M0_MSR_PMU_CTL0,
+ .perf_ctr = NHMEX_M0_MSR_PMU_CNT0,
+ .event_mask = NHMEX_M_PMON_RAW_EVENT_MASK,
+ .box_ctl = NHMEX_M0_MSR_GLOBAL_CTL,
+ .msr_offset = NHMEX_M_MSR_OFFSET,
+ .pair_ctr_ctl = 1,
+ .num_shared_regs = 8,
+ .event_descs = nhmex_uncore_mbox_events,
+ .ops = &nhmex_uncore_mbox_ops,
+ .format_group = &nhmex_uncore_mbox_format_group,
+};
+
+void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ int port;
+
+ /* adjust the main event selector */
+ if (reg1->idx % 2) {
+ reg1->idx--;
+ hwc->config -= 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
+ } else {
+ reg1->idx++;
+ hwc->config += 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
+ }
+
+ /* adjust address or config of extra register */
+ port = reg1->idx / 6 + box->pmu->pmu_idx * 4;
+ switch (reg1->idx % 6) {
+ case 0:
+ reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG0(port);
+ break;
+ case 1:
+ reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG1(port);
+ break;
+ case 2:
+ /* the 8~15 bits to the 0~7 bits */
+ reg1->config >>= 8;
+ break;
+ case 3:
+ /* the 0~7 bits to the 8~15 bits */
+ reg1->config <<= 8;
+ break;
+ case 4:
+ reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port);
+ break;
+ case 5:
+ reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port);
+ break;
+ };
+}
+
+/*
+ * Each rbox has 4 event set which monitor PQI port 0~3 or 4~7.
+ * An event set consists of 6 events, the 3rd and 4th events in
+ * an event set use the same extra register. So an event set uses
+ * 5 extra registers.
+ */
+static struct event_constraint *
+nhmex_rbox_get_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+ struct intel_uncore_extra_reg *er;
+ unsigned long flags;
+ int idx, er_idx;
+ u64 config1;
+ bool ok = false;
+
+ if (!uncore_box_is_fake(box) && reg1->alloc)
+ return NULL;
+
+ idx = reg1->idx % 6;
+ config1 = reg1->config;
+again:
+ er_idx = idx;
+ /* the 3rd and 4th events use the same extra register */
+ if (er_idx > 2)
+ er_idx--;
+ er_idx += (reg1->idx / 6) * 5;
+
+ er = &box->shared_regs[er_idx];
+ raw_spin_lock_irqsave(&er->lock, flags);
+ if (idx < 2) {
+ if (!atomic_read(&er->ref) || er->config == reg1->config) {
+ atomic_inc(&er->ref);
+ er->config = reg1->config;
+ ok = true;
+ }
+ } else if (idx == 2 || idx == 3) {
+ /*
+ * these two events use different fields in a extra register,
+ * the 0~7 bits and the 8~15 bits respectively.
+ */
+ u64 mask = 0xff << ((idx - 2) * 8);
+ if (!__BITS_VALUE(atomic_read(&er->ref), idx - 2, 8) ||
+ !((er->config ^ config1) & mask)) {
+ atomic_add(1 << ((idx - 2) * 8), &er->ref);
+ er->config &= ~mask;
+ er->config |= config1 & mask;
+ ok = true;
+ }
+ } else {
+ if (!atomic_read(&er->ref) ||
+ (er->config == (hwc->config >> 32) &&
+ er->config1 == reg1->config &&
+ er->config2 == reg2->config)) {
+ atomic_inc(&er->ref);
+ er->config = (hwc->config >> 32);
+ er->config1 = reg1->config;
+ er->config2 = reg2->config;
+ ok = true;
+ }
+ }
+ raw_spin_unlock_irqrestore(&er->lock, flags);
+
+ if (!ok) {
+ /*
+ * The Rbox events are always in pairs. The paired
+ * events are functional identical, but use different
+ * extra registers. If we failed to take an extra
+ * register, try the alternative.
+ */
+ if (idx % 2)
+ idx--;
+ else
+ idx++;
+ if (idx != reg1->idx % 6) {
+ if (idx == 2)
+ config1 >>= 8;
+ else if (idx == 3)
+ config1 <<= 8;
+ goto again;
+ }
+ } else {
+ if (!uncore_box_is_fake(box)) {
+ if (idx != reg1->idx % 6)
+ nhmex_rbox_alter_er(box, event);
+ reg1->alloc = 1;
+ }
+ return NULL;
+ }
+ return &constraint_empty;
+}
+
+static void nhmex_rbox_put_constraint(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct intel_uncore_extra_reg *er;
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ int idx, er_idx;
+
+ if (uncore_box_is_fake(box) || !reg1->alloc)
+ return;
+
+ idx = reg1->idx % 6;
+ er_idx = idx;
+ if (er_idx > 2)
+ er_idx--;
+ er_idx += (reg1->idx / 6) * 5;
+
+ er = &box->shared_regs[er_idx];
+ if (idx == 2 || idx == 3)
+ atomic_sub(1 << ((idx - 2) * 8), &er->ref);
+ else
+ atomic_dec(&er->ref);
+
+ reg1->alloc = 0;
+}
+
+static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &event->hw.extra_reg;
+ struct hw_perf_event_extra *reg2 = &event->hw.branch_reg;
+ int port, idx;
+
+ idx = (event->hw.config & NHMEX_R_PMON_CTL_EV_SEL_MASK) >>
+ NHMEX_R_PMON_CTL_EV_SEL_SHIFT;
+ if (idx >= 0x18)
+ return -EINVAL;
+
+ reg1->idx = idx;
+ reg1->config = event->attr.config1;
+
+ port = idx / 6 + box->pmu->pmu_idx * 4;
+ idx %= 6;
+ switch (idx) {
+ case 0:
+ reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG0(port);
+ break;
+ case 1:
+ reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG1(port);
+ break;
+ case 2:
+ case 3:
+ reg1->reg = NHMEX_R_MSR_PORTN_QLX_CFG(port);
+ break;
+ case 4:
+ case 5:
+ if (idx == 4)
+ reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port);
+ else
+ reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port);
+ reg2->config = event->attr.config2;
+ hwc->config |= event->attr.config & (~0ULL << 32);
+ break;
+ };
+ return 0;
+}
+
+static u64 nhmex_rbox_shared_reg_config(struct intel_uncore_box *box, int idx)
+{
+ struct intel_uncore_extra_reg *er;
+ unsigned long flags;
+ u64 config;
+
+ er = &box->shared_regs[idx];
+
+ raw_spin_lock_irqsave(&er->lock, flags);
+ config = er->config;
+ raw_spin_unlock_irqrestore(&er->lock, flags);
+
+ return config;
+}
+
+static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct perf_event *event)
+{
+ struct hw_perf_event *hwc = &event->hw;
+ struct hw_perf_event_extra *reg1 = &hwc->extra_reg;
+ struct hw_perf_event_extra *reg2 = &hwc->branch_reg;
+ int idx, er_idx;
+
+ idx = reg1->idx % 6;
+ er_idx = idx;
+ if (er_idx > 2)
+ er_idx--;
+ er_idx += (reg1->idx / 6) * 5;
+
+ switch (idx) {
+ case 0:
+ case 1:
+ wrmsrl(reg1->reg, reg1->config);
+ break;
+ case 2:
+ case 3:
+ wrmsrl(reg1->reg, nhmex_rbox_shared_reg_config(box, er_idx));
+ break;
+ case 4:
+ case 5:
+ wrmsrl(reg1->reg, reg1->config);
+ wrmsrl(reg1->reg + 1, hwc->config >> 32);
+ wrmsrl(reg1->reg + 2, reg2->config);
+ break;
+ };
+
+ wrmsrl(hwc->config_base, NHMEX_PMON_CTL_EN_BIT0 |
+ (hwc->config & NHMEX_R_PMON_CTL_EV_SEL_MASK));
+}
+
+DEFINE_UNCORE_FORMAT_ATTR(xbr_match, xbr_match, "config:32-63");
+DEFINE_UNCORE_FORMAT_ATTR(xbr_mm_cfg, xbr_mm_cfg, "config1:0-63");
+DEFINE_UNCORE_FORMAT_ATTR(xbr_mask, xbr_mask, "config2:0-63");
+DEFINE_UNCORE_FORMAT_ATTR(qlx_cfg, qlx_cfg, "config1:0-15");
+DEFINE_UNCORE_FORMAT_ATTR(iperf_cfg, iperf_cfg, "config1:0-31");
+
+static struct attribute *nhmex_uncore_rbox_formats_attr[] = {
+ &format_attr_event5.attr,
+ &format_attr_xbr_mm_cfg.attr,
+ &format_attr_xbr_match.attr,
+ &format_attr_xbr_mask.attr,
+ &format_attr_qlx_cfg.attr,
+ &format_attr_iperf_cfg.attr,
+ NULL,
+};
+
+static struct attribute_group nhmex_uncore_rbox_format_group = {
+ .name = "format",
+ .attrs = nhmex_uncore_rbox_formats_attr,
+};
+
+static struct uncore_event_desc nhmex_uncore_rbox_events[] = {
+ INTEL_UNCORE_EVENT_DESC(qpi0_flit_send, "event=0x0,iperf_cfg=0x80000000"),
+ INTEL_UNCORE_EVENT_DESC(qpi1_filt_send, "event=0x6,iperf_cfg=0x80000000"),
+ INTEL_UNCORE_EVENT_DESC(qpi0_idle_filt, "event=0x0,iperf_cfg=0x40000000"),
+ INTEL_UNCORE_EVENT_DESC(qpi1_idle_filt, "event=0x6,iperf_cfg=0x40000000"),
+ INTEL_UNCORE_EVENT_DESC(qpi0_date_response, "event=0x0,iperf_cfg=0xc4"),
+ INTEL_UNCORE_EVENT_DESC(qpi1_date_response, "event=0x6,iperf_cfg=0xc4"),
+ { /* end: all zeroes */ },
+};
+
+static struct intel_uncore_ops nhmex_uncore_rbox_ops = {
+ NHMEX_UNCORE_OPS_COMMON_INIT(),
+ .enable_event = nhmex_rbox_msr_enable_event,
+ .hw_config = nhmex_rbox_hw_config,
+ .get_constraint = nhmex_rbox_get_constraint,
+ .put_constraint = nhmex_rbox_put_constraint,
+};
+
+static struct intel_uncore_type nhmex_uncore_rbox = {
+ .name = "rbox",
+ .num_counters = 8,
+ .num_boxes = 2,
+ .perf_ctr_bits = 48,
+ .event_ctl = NHMEX_R_MSR_PMON_CTL0,
+ .perf_ctr = NHMEX_R_MSR_PMON_CNT0,
+ .event_mask = NHMEX_R_PMON_RAW_EVENT_MASK,
+ .box_ctl = NHMEX_R_MSR_GLOBAL_CTL,
+ .msr_offset = NHMEX_R_MSR_OFFSET,
+ .pair_ctr_ctl = 1,
+ .num_shared_regs = 20,
+ .event_descs = nhmex_uncore_rbox_events,
+ .ops = &nhmex_uncore_rbox_ops,
+ .format_group = &nhmex_uncore_rbox_format_group
+};
+
+static struct intel_uncore_type *nhmex_msr_uncores[] = {
+ &nhmex_uncore_ubox,
+ &nhmex_uncore_cbox,
+ &nhmex_uncore_bbox,
+ &nhmex_uncore_sbox,
+ &nhmex_uncore_mbox,
+ &nhmex_uncore_rbox,
+ &nhmex_uncore_wbox,
+ NULL,
+};
+/* end of Nehalem-EX uncore support */
+
+static void uncore_assign_hw_event(struct intel_uncore_box *box, struct perf_event *event, int idx)
{
struct hw_perf_event *hwc = &event->hw;
@@ -787,8 +1841,7 @@ static void uncore_assign_hw_event(struct intel_uncore_box *box,
hwc->event_base = uncore_perf_ctr(box, hwc->idx);
}
-static void uncore_perf_event_update(struct intel_uncore_box *box,
- struct perf_event *event)
+static void uncore_perf_event_update(struct intel_uncore_box *box, struct perf_event *event)
{
u64 prev_count, new_count, delta;
int shift;
@@ -858,14 +1911,12 @@ static void uncore_pmu_init_hrtimer(struct intel_uncore_box *box)
box->hrtimer.function = uncore_pmu_hrtimer;
}
-struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type,
- int cpu)
+struct intel_uncore_box *uncore_alloc_box(struct intel_uncore_type *type, int cpu)
{
struct intel_uncore_box *box;
int i, size;
- size = sizeof(*box) + type->num_shared_regs *
- sizeof(struct intel_uncore_extra_reg);
+ size = sizeof(*box) + type->num_shared_regs * sizeof(struct intel_uncore_extra_reg);
box = kmalloc_node(size, GFP_KERNEL | __GFP_ZERO, cpu_to_node(cpu));
if (!box)
@@ -915,12 +1966,11 @@ static struct intel_uncore_box *uncore_event_to_box(struct perf_event *event)
* perf core schedules event on the basis of cpu, uncore events are
* collected by one of the cpus inside a physical package.
*/
- return uncore_pmu_to_box(uncore_event_to_pmu(event),
- smp_processor_id());
+ return uncore_pmu_to_box(uncore_event_to_pmu(event), smp_processor_id());
}
-static int uncore_collect_events(struct intel_uncore_box *box,
- struct perf_event *leader, bool dogrp)
+static int
+uncore_collect_events(struct intel_uncore_box *box, struct perf_event *leader, bool dogrp)
{
struct perf_event *event;
int n, max_count;
@@ -952,8 +2002,7 @@ static int uncore_collect_events(struct intel_uncore_box *box,
}
static struct event_constraint *
-uncore_get_event_constraint(struct intel_uncore_box *box,
- struct perf_event *event)
+uncore_get_event_constraint(struct intel_uncore_box *box, struct perf_event *event)
{
struct intel_uncore_type *type = box->pmu->type;
struct event_constraint *c;
@@ -977,15 +2026,13 @@ uncore_get_event_constraint(struct intel_uncore_box *box,
return &type->unconstrainted;
}
-static void uncore_put_event_constraint(struct intel_uncore_box *box,
- struct perf_event *event)
+static void uncore_put_event_constraint(struct intel_uncore_box *box, struct perf_event *event)
{
if (box->pmu->type->ops->put_constraint)
box->pmu->type->ops->put_constraint(box, event);
}
-static int uncore_assign_events(struct intel_uncore_box *box,
- int assign[], int n)
+static int uncore_assign_events(struct intel_uncore_box *box, int assign[], int n)
{
unsigned long used_mask[BITS_TO_LONGS(UNCORE_PMC_IDX_MAX)];
struct event_constraint *c, *constraints[UNCORE_PMC_IDX_MAX];
@@ -1407,8 +2454,7 @@ static bool pcidrv_registered;
/*
* add a pci uncore device
*/
-static int __devinit uncore_pci_add(struct intel_uncore_type *type,
- struct pci_dev *pdev)
+static int __devinit uncore_pci_add(struct intel_uncore_type *type, struct pci_dev *pdev)
{
struct intel_uncore_pmu *pmu;
struct intel_uncore_box *box;
@@ -1485,6 +2531,7 @@ static int __devinit uncore_pci_probe(struct pci_dev *pdev,
struct intel_uncore_type *type;
type = (struct intel_uncore_type *)id->driver_data;
+
return uncore_pci_add(type, pdev);
}
@@ -1612,8 +2659,8 @@ static int __cpuinit uncore_cpu_prepare(int cpu, int phys_id)
return 0;
}
-static void __cpuinit uncore_change_context(struct intel_uncore_type **uncores,
- int old_cpu, int new_cpu)
+static void __cpuinit
+uncore_change_context(struct intel_uncore_type **uncores, int old_cpu, int new_cpu)
{
struct intel_uncore_type *type;
struct intel_uncore_pmu *pmu;
@@ -1694,8 +2741,8 @@ static void __cpuinit uncore_event_init_cpu(int cpu)
uncore_change_context(pci_uncores, -1, cpu);
}
-static int __cpuinit uncore_cpu_notifier(struct notifier_block *self,
- unsigned long action, void *hcpu)
+static int
+ __cpuinit uncore_cpu_notifier(struct notifier_block *self, unsigned long action, void *hcpu)
{
unsigned int cpu = (long)hcpu;
@@ -1732,12 +2779,12 @@ static int __cpuinit uncore_cpu_notifier(struct notifier_block *self,
}
static struct notifier_block uncore_cpu_nb __cpuinitdata = {
- .notifier_call = uncore_cpu_notifier,
+ .notifier_call = uncore_cpu_notifier,
/*
* to migrate uncore events, our notifier should be executed
* before perf core's notifier.
*/
- .priority = CPU_PRI_PERF + 1,
+ .priority = CPU_PRI_PERF + 1,
};
static void __init uncore_cpu_setup(void *dummy)
@@ -1767,6 +2814,9 @@ static int __init uncore_cpu_init(void)
snbep_uncore_cbox.num_boxes = max_cores;
msr_uncores = snbep_msr_uncores;
break;
+ case 46:
+ msr_uncores = nhmex_msr_uncores;
+ break;
default:
return 0;
}
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h
index b13e9ea81de..f3851892e07 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h
+++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h
@@ -5,8 +5,6 @@
#include "perf_event.h"
#define UNCORE_PMU_NAME_LEN 32
-#define UNCORE_BOX_HASH_SIZE 8
-
#define UNCORE_PMU_HRTIMER_INTERVAL (60 * NSEC_PER_SEC)
#define UNCORE_FIXED_EVENT 0xff
@@ -115,6 +113,10 @@
SNBEP_PCU_MSR_PMON_CTL_OCC_INVERT | \
SNBEP_PCU_MSR_PMON_CTL_OCC_EDGE_DET)
+#define SNBEP_QPI_PCI_PMON_RAW_EVENT_MASK \
+ (SNBEP_PMON_RAW_EVENT_MASK | \
+ SNBEP_PMON_CTL_EV_SEL_EXT)
+
/* SNB-EP pci control register */
#define SNBEP_PCI_PMON_BOX_CTL 0xf4
#define SNBEP_PCI_PMON_CTL0 0xd8
@@ -158,6 +160,193 @@
#define SNBEP_PCU_MSR_CORE_C3_CTR 0x3fc
#define SNBEP_PCU_MSR_CORE_C6_CTR 0x3fd
+/* NHM-EX event control */
+#define NHMEX_PMON_CTL_EV_SEL_MASK 0x000000ff
+#define NHMEX_PMON_CTL_UMASK_MASK 0x0000ff00
+#define NHMEX_PMON_CTL_EN_BIT0 (1 << 0)
+#define NHMEX_PMON_CTL_EDGE_DET (1 << 18)
+#define NHMEX_PMON_CTL_PMI_EN (1 << 20)
+#define NHMEX_PMON_CTL_EN_BIT22 (1 << 22)
+#define NHMEX_PMON_CTL_INVERT (1 << 23)
+#define NHMEX_PMON_CTL_TRESH_MASK 0xff000000
+#define NHMEX_PMON_RAW_EVENT_MASK (NHMEX_PMON_CTL_EV_SEL_MASK | \
+ NHMEX_PMON_CTL_UMASK_MASK | \
+ NHMEX_PMON_CTL_EDGE_DET | \
+ NHMEX_PMON_CTL_INVERT | \
+ NHMEX_PMON_CTL_TRESH_MASK)
+
+/* NHM-EX Ubox */
+#define NHMEX_U_MSR_PMON_GLOBAL_CTL 0xc00
+#define NHMEX_U_MSR_PMON_CTR 0xc11
+#define NHMEX_U_MSR_PMON_EV_SEL 0xc10
+
+#define NHMEX_U_PMON_GLOBAL_EN (1 << 0)
+#define NHMEX_U_PMON_GLOBAL_PMI_CORE_SEL 0x0000001e
+#define NHMEX_U_PMON_GLOBAL_EN_ALL (1 << 28)
+#define NHMEX_U_PMON_GLOBAL_RST_ALL (1 << 29)
+#define NHMEX_U_PMON_GLOBAL_FRZ_ALL (1 << 31)
+
+#define NHMEX_U_PMON_RAW_EVENT_MASK \
+ (NHMEX_PMON_CTL_EV_SEL_MASK | \
+ NHMEX_PMON_CTL_EDGE_DET)
+
+/* NHM-EX Cbox */
+#define NHMEX_C0_MSR_PMON_GLOBAL_CTL 0xd00
+#define NHMEX_C0_MSR_PMON_CTR0 0xd11
+#define NHMEX_C0_MSR_PMON_EV_SEL0 0xd10
+#define NHMEX_C_MSR_OFFSET 0x20
+
+/* NHM-EX Bbox */
+#define NHMEX_B0_MSR_PMON_GLOBAL_CTL 0xc20
+#define NHMEX_B0_MSR_PMON_CTR0 0xc31
+#define NHMEX_B0_MSR_PMON_CTL0 0xc30
+#define NHMEX_B_MSR_OFFSET 0x40
+#define NHMEX_B0_MSR_MATCH 0xe45
+#define NHMEX_B0_MSR_MASK 0xe46
+#define NHMEX_B1_MSR_MATCH 0xe4d
+#define NHMEX_B1_MSR_MASK 0xe4e
+
+#define NHMEX_B_PMON_CTL_EN (1 << 0)
+#define NHMEX_B_PMON_CTL_EV_SEL_SHIFT 1
+#define NHMEX_B_PMON_CTL_EV_SEL_MASK \
+ (0x1f << NHMEX_B_PMON_CTL_EV_SEL_SHIFT)
+#define NHMEX_B_PMON_CTR_SHIFT 6
+#define NHMEX_B_PMON_CTR_MASK \
+ (0x3 << NHMEX_B_PMON_CTR_SHIFT)
+#define NHMEX_B_PMON_RAW_EVENT_MASK \
+ (NHMEX_B_PMON_CTL_EV_SEL_MASK | \
+ NHMEX_B_PMON_CTR_MASK)
+
+/* NHM-EX Sbox */
+#define NHMEX_S0_MSR_PMON_GLOBAL_CTL 0xc40
+#define NHMEX_S0_MSR_PMON_CTR0 0xc51
+#define NHMEX_S0_MSR_PMON_CTL0 0xc50
+#define NHMEX_S_MSR_OFFSET 0x80
+#define NHMEX_S0_MSR_MM_CFG 0xe48
+#define NHMEX_S0_MSR_MATCH 0xe49
+#define NHMEX_S0_MSR_MASK 0xe4a
+#define NHMEX_S1_MSR_MM_CFG 0xe58
+#define NHMEX_S1_MSR_MATCH 0xe59
+#define NHMEX_S1_MSR_MASK 0xe5a
+
+#define NHMEX_S_PMON_MM_CFG_EN (0x1ULL << 63)
+
+/* NHM-EX Mbox */
+#define NHMEX_M0_MSR_GLOBAL_CTL 0xca0
+#define NHMEX_M0_MSR_PMU_DSP 0xca5
+#define NHMEX_M0_MSR_PMU_ISS 0xca6
+#define NHMEX_M0_MSR_PMU_MAP 0xca7
+#define NHMEX_M0_MSR_PMU_MSC_THR 0xca8
+#define NHMEX_M0_MSR_PMU_PGT 0xca9
+#define NHMEX_M0_MSR_PMU_PLD 0xcaa
+#define NHMEX_M0_MSR_PMU_ZDP_CTL_FVC 0xcab
+#define NHMEX_M0_MSR_PMU_CTL0 0xcb0
+#define NHMEX_M0_MSR_PMU_CNT0 0xcb1
+#define NHMEX_M_MSR_OFFSET 0x40
+#define NHMEX_M0_MSR_PMU_MM_CFG 0xe54
+#define NHMEX_M1_MSR_PMU_MM_CFG 0xe5c
+
+#define NHMEX_M_PMON_MM_CFG_EN (1ULL << 63)
+#define NHMEX_M_PMON_ADDR_MATCH_MASK 0x3ffffffffULL
+#define NHMEX_M_PMON_ADDR_MASK_MASK 0x7ffffffULL
+#define NHMEX_M_PMON_ADDR_MASK_SHIFT 34
+
+#define NHMEX_M_PMON_CTL_EN (1 << 0)
+#define NHMEX_M_PMON_CTL_PMI_EN (1 << 1)
+#define NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT 2
+#define NHMEX_M_PMON_CTL_COUNT_MODE_MASK \
+ (0x3 << NHMEX_M_PMON_CTL_COUNT_MODE_SHIFT)
+#define NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT 4
+#define NHMEX_M_PMON_CTL_STORAGE_MODE_MASK \
+ (0x3 << NHMEX_M_PMON_CTL_STORAGE_MODE_SHIFT)
+#define NHMEX_M_PMON_CTL_WRAP_MODE (1 << 6)
+#define NHMEX_M_PMON_CTL_FLAG_MODE (1 << 7)
+#define NHMEX_M_PMON_CTL_INC_SEL_SHIFT 9
+#define NHMEX_M_PMON_CTL_INC_SEL_MASK \
+ (0x1f << NHMEX_M_PMON_CTL_INC_SEL_SHIFT)
+#define NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT 19
+#define NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK \
+ (0x7 << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT)
+#define NHMEX_M_PMON_RAW_EVENT_MASK \
+ (NHMEX_M_PMON_CTL_COUNT_MODE_MASK | \
+ NHMEX_M_PMON_CTL_STORAGE_MODE_MASK | \
+ NHMEX_M_PMON_CTL_WRAP_MODE | \
+ NHMEX_M_PMON_CTL_FLAG_MODE | \
+ NHMEX_M_PMON_CTL_INC_SEL_MASK | \
+ NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK)
+
+
+#define NHMEX_M_PMON_ZDP_CTL_FVC_FVID_MASK 0x1f
+#define NHMEX_M_PMON_ZDP_CTL_FVC_BCMD_MASK (0x7 << 5)
+#define NHMEX_M_PMON_ZDP_CTL_FVC_RSP_MASK (0x7 << 8)
+#define NHMEX_M_PMON_ZDP_CTL_FVC_PBOX_INIT_ERR (1 << 23)
+#define NHMEX_M_PMON_ZDP_CTL_FVC_MASK \
+ (NHMEX_M_PMON_ZDP_CTL_FVC_FVID_MASK | \
+ NHMEX_M_PMON_ZDP_CTL_FVC_BCMD_MASK | \
+ NHMEX_M_PMON_ZDP_CTL_FVC_RSP_MASK | \
+ NHMEX_M_PMON_ZDP_CTL_FVC_PBOX_INIT_ERR)
+#define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7 << (11 + 3 * (n)))
+
+/*
+ * use the 9~13 bits to select event If the 7th bit is not set,
+ * otherwise use the 19~21 bits to select event.
+ */
+#define MBOX_INC_SEL(x) ((x) << NHMEX_M_PMON_CTL_INC_SEL_SHIFT)
+#define MBOX_SET_FLAG_SEL(x) (((x) << NHMEX_M_PMON_CTL_SET_FLAG_SEL_SHIFT) | \
+ NHMEX_M_PMON_CTL_FLAG_MODE)
+#define MBOX_INC_SEL_MASK (NHMEX_M_PMON_CTL_INC_SEL_MASK | \
+ NHMEX_M_PMON_CTL_FLAG_MODE)
+#define MBOX_SET_FLAG_SEL_MASK (NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK | \
+ NHMEX_M_PMON_CTL_FLAG_MODE)
+#define MBOX_INC_SEL_EXTAR_REG(c, r) \
+ EVENT_EXTRA_REG(MBOX_INC_SEL(c), NHMEX_M0_MSR_PMU_##r, \
+ MBOX_INC_SEL_MASK, (u64)-1, NHMEX_M_##r)
+#define MBOX_SET_FLAG_SEL_EXTRA_REG(c, r) \
+ EVENT_EXTRA_REG(MBOX_SET_FLAG_SEL(c), NHMEX_M0_MSR_PMU_##r, \
+ MBOX_SET_FLAG_SEL_MASK, \
+ (u64)-1, NHMEX_M_##r)
+
+/* NHM-EX Rbox */
+#define NHMEX_R_MSR_GLOBAL_CTL 0xe00
+#define NHMEX_R_MSR_PMON_CTL0 0xe10
+#define NHMEX_R_MSR_PMON_CNT0 0xe11
+#define NHMEX_R_MSR_OFFSET 0x20
+
+#define NHMEX_R_MSR_PORTN_QLX_CFG(n) \
+ ((n) < 4 ? (0xe0c + (n)) : (0xe2c + (n) - 4))
+#define NHMEX_R_MSR_PORTN_IPERF_CFG0(n) (0xe04 + (n))
+#define NHMEX_R_MSR_PORTN_IPERF_CFG1(n) (0xe24 + (n))
+#define NHMEX_R_MSR_PORTN_XBR_OFFSET(n) \
+ (((n) < 4 ? 0 : 0x10) + (n) * 4)
+#define NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) \
+ (0xe60 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n))
+#define NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(n) \
+ (NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 1)
+#define NHMEX_R_MSR_PORTN_XBR_SET1_MASK(n) \
+ (NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(n) + 2)
+#define NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) \
+ (0xe70 + NHMEX_R_MSR_PORTN_XBR_OFFSET(n))
+#define NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(n) \
+ (NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 1)
+#define NHMEX_R_MSR_PORTN_XBR_SET2_MASK(n) \
+ (NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(n) + 2)
+
+#define NHMEX_R_PMON_CTL_EN (1 << 0)
+#define NHMEX_R_PMON_CTL_EV_SEL_SHIFT 1
+#define NHMEX_R_PMON_CTL_EV_SEL_MASK \
+ (0x1f << NHMEX_R_PMON_CTL_EV_SEL_SHIFT)
+#define NHMEX_R_PMON_CTL_PMI_EN (1 << 6)
+#define NHMEX_R_PMON_RAW_EVENT_MASK NHMEX_R_PMON_CTL_EV_SEL_MASK
+
+/* NHM-EX Wbox */
+#define NHMEX_W_MSR_GLOBAL_CTL 0xc80
+#define NHMEX_W_MSR_PMON_CNT0 0xc90
+#define NHMEX_W_MSR_PMON_EVT_SEL0 0xc91
+#define NHMEX_W_MSR_PMON_FIXED_CTR 0x394
+#define NHMEX_W_MSR_PMON_FIXED_CTL 0x395
+
+#define NHMEX_W_PMON_GLOBAL_FIXED_EN (1ULL << 31)
+
struct intel_uncore_ops;
struct intel_uncore_pmu;
struct intel_uncore_box;
@@ -178,6 +367,7 @@ struct intel_uncore_type {
unsigned msr_offset;
unsigned num_shared_regs:8;
unsigned single_fixed:1;
+ unsigned pair_ctr_ctl:1;
struct event_constraint unconstrainted;
struct event_constraint *constraints;
struct intel_uncore_pmu *pmus;
@@ -213,7 +403,7 @@ struct intel_uncore_pmu {
struct intel_uncore_extra_reg {
raw_spinlock_t lock;
- u64 config1;
+ u64 config, config1, config2;
atomic_t ref;
};
@@ -323,14 +513,16 @@ unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box)
static inline
unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx)
{
- return idx + box->pmu->type->event_ctl +
+ return box->pmu->type->event_ctl +
+ (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
box->pmu->type->msr_offset * box->pmu->pmu_idx;
}
static inline
unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx)
{
- return idx + box->pmu->type->perf_ctr +
+ return box->pmu->type->perf_ctr +
+ (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) +
box->pmu->type->msr_offset * box->pmu->pmu_idx;
}
@@ -422,3 +614,8 @@ static inline void uncore_box_init(struct intel_uncore_box *box)
box->pmu->type->ops->init_box(box);
}
}
+
+static inline bool uncore_box_is_fake(struct intel_uncore_box *box)
+{
+ return (box->phys_id < 0);
+}
diff --git a/arch/x86/kernel/e820.c b/arch/x86/kernel/e820.c
index 41857970517..ed858e9e9a7 100644
--- a/arch/x86/kernel/e820.c
+++ b/arch/x86/kernel/e820.c
@@ -944,7 +944,7 @@ void __init e820_reserve_resources(void)
for (i = 0; i < e820_saved.nr_map; i++) {
struct e820entry *entry = &e820_saved.map[i];
firmware_map_add_early(entry->addr,
- entry->addr + entry->size - 1,
+ entry->addr + entry->size,
e820_type_to_string(entry->type));
}
}
diff --git a/arch/x86/um/asm/ptrace.h b/arch/x86/um/asm/ptrace.h
index 950dfb7b841..e72cd0df5ba 100644
--- a/arch/x86/um/asm/ptrace.h
+++ b/arch/x86/um/asm/ptrace.h
@@ -30,10 +30,10 @@
#define profile_pc(regs) PT_REGS_IP(regs)
#define UPT_RESTART_SYSCALL(r) (UPT_IP(r) -= 2)
-#define UPT_SET_SYSCALL_RETURN(r, res) (UPT_AX(r) = (res))
+#define PT_REGS_SET_SYSCALL_RETURN(r, res) (PT_REGS_AX(r) = (res))
-static inline long regs_return_value(struct uml_pt_regs *regs)
+static inline long regs_return_value(struct pt_regs *regs)
{
- return UPT_AX(regs);
+ return PT_REGS_AX(regs);
}
#endif /* __UM_X86_PTRACE_H */
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig
index 8a3f8351f43..8ed64cfae4f 100644
--- a/arch/xtensa/Kconfig
+++ b/arch/xtensa/Kconfig
@@ -7,6 +7,7 @@ config ZONE_DMA
config XTENSA
def_bool y
select HAVE_IDE
+ select GENERIC_ATOMIC64
select HAVE_GENERIC_HARDIRQS
select GENERIC_IRQ_SHOW
select GENERIC_CPU_DEVICES
diff --git a/arch/xtensa/include/asm/cpumask.h b/arch/xtensa/include/asm/cpumask.h
deleted file mode 100644
index ebeede397db..00000000000
--- a/arch/xtensa/include/asm/cpumask.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * include/asm-xtensa/cpumask.h
- *
- * 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) 2001 - 2005 Tensilica Inc.
- */
-
-#ifndef _XTENSA_CPUMASK_H
-#define _XTENSA_CPUMASK_H
-
-#include <asm-generic/cpumask.h>
-
-#endif /* _XTENSA_CPUMASK_H */
diff --git a/arch/xtensa/include/asm/rmap.h b/arch/xtensa/include/asm/rmap.h
deleted file mode 100644
index 649588b7e9a..00000000000
--- a/arch/xtensa/include/asm/rmap.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * include/asm-xtensa/rmap.h
- *
- * 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) 2001 - 2005 Tensilica Inc.
- */
-
-#ifndef _XTENSA_RMAP_H
-#define _XTENSA_RMAP_H
-
-#include <asm-generic/rmap.h>
-
-#endif
diff --git a/arch/xtensa/kernel/syscall.c b/arch/xtensa/kernel/syscall.c
index 816e6d0d686..05b3f093d5d 100644
--- a/arch/xtensa/kernel/syscall.c
+++ b/arch/xtensa/kernel/syscall.c
@@ -44,7 +44,7 @@ asmlinkage long xtensa_shmat(int shmid, char __user *shmaddr, int shmflg)
unsigned long ret;
long err;
- err = do_shmat(shmid, shmaddr, shmflg, &ret);
+ err = do_shmat(shmid, shmaddr, shmflg, &ret, SHMLBA);
if (err)
return err;
return (long)ret;
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c
index b17885a0b50..5a74c53bc69 100644
--- a/arch/xtensa/mm/fault.c
+++ b/arch/xtensa/mm/fault.c
@@ -44,6 +44,7 @@ void do_page_fault(struct pt_regs *regs)
int is_write, is_exec;
int fault;
+ unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE;
info.si_code = SEGV_MAPERR;
@@ -71,6 +72,7 @@ void do_page_fault(struct pt_regs *regs)
address, exccause, regs->pc, is_write? "w":"", is_exec? "x":"");
#endif
+retry:
down_read(&mm->mmap_sem);
vma = find_vma(mm, address);
@@ -93,6 +95,7 @@ good_area:
if (is_write) {
if (!(vma->vm_flags & VM_WRITE))
goto bad_area;
+ flags |= FAULT_FLAG_WRITE;
} else if (is_exec) {
if (!(vma->vm_flags & VM_EXEC))
goto bad_area;
@@ -104,7 +107,11 @@ good_area:
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
- fault = handle_mm_fault(mm, vma, address, is_write ? FAULT_FLAG_WRITE : 0);
+ fault = handle_mm_fault(mm, vma, address, flags);
+
+ if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current))
+ return;
+
if (unlikely(fault & VM_FAULT_ERROR)) {
if (fault & VM_FAULT_OOM)
goto out_of_memory;
@@ -112,10 +119,22 @@ good_area:
goto do_sigbus;
BUG();
}
- if (fault & VM_FAULT_MAJOR)
- current->maj_flt++;
- else
- current->min_flt++;
+ if (flags & FAULT_FLAG_ALLOW_RETRY) {
+ if (fault & VM_FAULT_MAJOR)
+ current->maj_flt++;
+ else
+ current->min_flt++;
+ if (fault & VM_FAULT_RETRY) {
+ flags &= ~FAULT_FLAG_ALLOW_RETRY;
+
+ /* No need to up_read(&mm->mmap_sem) as we would
+ * have already released it in __lock_page_or_retry
+ * in mm/filemap.c.
+ */
+
+ goto retry;
+ }
+ }
up_read(&mm->mmap_sem);
return;