summaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/Kconfig9
-rw-r--r--arch/arm/Kconfig.debug220
-rw-r--r--arch/arm/Makefile1
-rw-r--r--arch/arm/boot/compressed/head.S41
-rw-r--r--arch/arm/boot/dts/Makefile1
-rw-r--r--arch/arm/boot/dts/am335x-evm.dts1
-rw-r--r--arch/arm/boot/dts/am3517.dtsi1
-rw-r--r--arch/arm/boot/dts/armada-370-netgear-rn102.dts1
-rw-r--r--arch/arm/boot/dts/armada-370-netgear-rn104.dts1
-rw-r--r--arch/arm/boot/dts/armada-38x.dtsi7
-rw-r--r--arch/arm/boot/dts/armada-xp-netgear-rn2120.dts1
-rw-r--r--arch/arm/boot/dts/at91sam9263.dtsi2
-rw-r--r--arch/arm/boot/dts/berlin2q-marvell-dmp.dts2
-rw-r--r--arch/arm/boot/dts/berlin2q.dtsi63
-rw-r--r--arch/arm/boot/dts/dra7-evm.dts10
-rw-r--r--arch/arm/boot/dts/dra7.dtsi6
-rw-r--r--arch/arm/boot/dts/exynos4.dtsi13
-rw-r--r--arch/arm/boot/dts/exynos4210-origen.dts1
-rw-r--r--arch/arm/boot/dts/exynos4210-smdkv310.dts1
-rw-r--r--arch/arm/boot/dts/exynos4210-trats.dts1
-rw-r--r--arch/arm/boot/dts/exynos4210-universal_c210.dts1
-rw-r--r--arch/arm/boot/dts/exynos4210.dtsi9
-rw-r--r--arch/arm/boot/dts/exynos4412-odroid-common.dtsi31
-rw-r--r--arch/arm/boot/dts/exynos4412-odroidu3.dts8
-rw-r--r--arch/arm/boot/dts/exynos4412-odroidx2.dts8
-rw-r--r--arch/arm/boot/dts/exynos4412-origen.dts1
-rw-r--r--arch/arm/boot/dts/exynos4412-smdk4412.dts1
-rw-r--r--arch/arm/boot/dts/exynos4412-tiny4412.dts4
-rw-r--r--arch/arm/boot/dts/exynos4412-trats2.dts1
-rw-r--r--arch/arm/boot/dts/exynos4x12.dtsi14
-rw-r--r--arch/arm/boot/dts/exynos5250.dtsi2
-rw-r--r--arch/arm/boot/dts/exynos5420-arndale-octa.dts4
-rw-r--r--arch/arm/boot/dts/exynos5420.dtsi6
-rw-r--r--arch/arm/boot/dts/imx25.dtsi10
-rw-r--r--arch/arm/boot/dts/imx51-babbage.dts22
-rw-r--r--arch/arm/boot/dts/imx6qdl.dtsi4
-rw-r--r--arch/arm/boot/dts/imx6sx-sdb.dts15
-rw-r--r--arch/arm/boot/dts/ls1021a.dtsi1
-rw-r--r--arch/arm/boot/dts/omap3-n900.dts4
-rw-r--r--arch/arm/boot/dts/r8a7790-lager.dts6
-rw-r--r--arch/arm/boot/dts/r8a7791-koelsch.dts4
-rw-r--r--arch/arm/boot/dts/rk3288-evb-rk808.dts23
-rw-r--r--arch/arm/boot/dts/rk3288-evb.dtsi49
-rw-r--r--arch/arm/boot/dts/rk3288.dtsi54
-rw-r--r--arch/arm/boot/dts/sama5d3xmb.dtsi2
-rw-r--r--arch/arm/boot/dts/sama5d4.dtsi2
-rw-r--r--arch/arm/boot/dts/ste-nomadik-nhk15.dts8
-rw-r--r--arch/arm/boot/dts/stih415.dtsi12
-rw-r--r--arch/arm/boot/dts/stih416.dtsi22
-rw-r--r--arch/arm/boot/dts/sun4i-a10.dtsi8
-rw-r--r--arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts6
-rw-r--r--arch/arm/boot/dts/sun5i-a10s.dtsi4
-rw-r--r--arch/arm/boot/dts/sun5i-a13-hsg-h702.dts4
-rw-r--r--arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts4
-rw-r--r--arch/arm/boot/dts/sun5i-a13-olinuxino.dts4
-rw-r--r--arch/arm/boot/dts/sun5i-a13.dtsi5
-rw-r--r--arch/arm/boot/dts/sun6i-a31.dtsi6
-rw-r--r--arch/arm/boot/dts/sun7i-a20-bananapi.dts6
-rw-r--r--arch/arm/boot/dts/sun7i-a20-hummingbird.dts8
-rw-r--r--arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts3
-rw-r--r--arch/arm/boot/dts/sun7i-a20.dtsi8
-rw-r--r--arch/arm/boot/dts/sun8i-a23.dtsi9
-rw-r--r--arch/arm/boot/dts/sun9i-a80-optimus.dts5
-rw-r--r--arch/arm/boot/dts/sun9i-a80.dtsi10
-rw-r--r--arch/arm/boot/dts/tegra124-jetson-tk1.dts7
-rw-r--r--arch/arm/boot/dts/tegra20-seaboard.dts2
-rw-r--r--arch/arm/boot/dts/versatile-ab.dts5
-rw-r--r--arch/arm/boot/dts/versatile-pb.dts37
-rw-r--r--arch/arm/boot/dts/vf610-twr.dts15
-rw-r--r--arch/arm/boot/dts/zynq-parallella.dts2
-rw-r--r--arch/arm/configs/at91_dt_defconfig10
-rw-r--r--arch/arm/configs/exynos_defconfig18
-rw-r--r--arch/arm/configs/iop32x_defconfig1
-rw-r--r--arch/arm/configs/iop33x_defconfig1
-rw-r--r--arch/arm/configs/ixp4xx_defconfig1
-rw-r--r--arch/arm/configs/lager_defconfig150
-rw-r--r--arch/arm/configs/lpc32xx_defconfig1
-rw-r--r--arch/arm/configs/multi_v7_defconfig1
-rw-r--r--arch/arm/configs/mv78xx0_defconfig1
-rw-r--r--arch/arm/configs/mvebu_v7_defconfig1
-rw-r--r--arch/arm/configs/omap2plus_defconfig2
-rw-r--r--arch/arm/configs/orion5x_defconfig1
-rw-r--r--arch/arm/configs/rpc_defconfig1
-rw-r--r--arch/arm/configs/shmobile_defconfig1
-rw-r--r--arch/arm/include/asm/bitrev.h20
-rw-r--r--arch/arm/include/asm/compiler.h15
-rw-r--r--arch/arm/include/asm/insn.h (renamed from arch/arm/kernel/insn.h)0
-rw-r--r--arch/arm/include/asm/kprobes.h33
-rw-r--r--arch/arm/include/asm/kvm_asm.h1
-rw-r--r--arch/arm/include/asm/kvm_emulate.h15
-rw-r--r--arch/arm/include/asm/kvm_host.h9
-rw-r--r--arch/arm/include/asm/kvm_mmio.h1
-rw-r--r--arch/arm/include/asm/kvm_mmu.h98
-rw-r--r--arch/arm/include/asm/mach/irda.h20
-rw-r--r--arch/arm/include/asm/mach/pci.h6
-rw-r--r--arch/arm/include/asm/outercache.h3
-rw-r--r--arch/arm/include/asm/patch.h (renamed from arch/arm/kernel/patch.h)0
-rw-r--r--arch/arm/include/asm/pci.h7
-rw-r--r--arch/arm/include/asm/pgtable-2level.h3
-rw-r--r--arch/arm/include/asm/pgtable-3level.h7
-rw-r--r--arch/arm/include/asm/pgtable-nommu.h4
-rw-r--r--arch/arm/include/asm/pgtable.h20
-rw-r--r--arch/arm/include/asm/probes.h15
-rw-r--r--arch/arm/include/asm/thread_info.h4
-rw-r--r--arch/arm/include/asm/xen/page.h2
-rw-r--r--arch/arm/include/debug/at91.S (renamed from arch/arm/mach-at91/include/mach/debug-macro.S)19
-rw-r--r--arch/arm/include/debug/digicolor.S35
-rw-r--r--arch/arm/include/debug/ks8695.S (renamed from arch/arm/mach-ks8695/include/mach/debug-macro.S)10
-rw-r--r--arch/arm/include/debug/msm.S6
-rw-r--r--arch/arm/include/debug/netx.S (renamed from arch/arm/mach-netx/include/mach/debug-macro.S)22
-rw-r--r--arch/arm/include/debug/sirf.S30
-rw-r--r--arch/arm/include/uapi/asm/kvm.h2
-rw-r--r--arch/arm/kernel/Makefile16
-rw-r--r--arch/arm/kernel/bios32.c8
-rw-r--r--arch/arm/kernel/entry-armv.S3
-rw-r--r--arch/arm/kernel/entry-header.S13
-rw-r--r--arch/arm/kernel/entry-v7m.S2
-rw-r--r--arch/arm/kernel/ftrace.c3
-rw-r--r--arch/arm/kernel/head.S9
-rw-r--r--arch/arm/kernel/irq.c3
-rw-r--r--arch/arm/kernel/jump_label.c5
-rw-r--r--arch/arm/kernel/kgdb.c3
-rw-r--r--arch/arm/kernel/module.c2
-rw-r--r--arch/arm/kernel/patch.c3
-rw-r--r--arch/arm/kernel/perf_event.c10
-rw-r--r--arch/arm/kernel/setup.c7
-rw-r--r--arch/arm/kernel/signal.c4
-rw-r--r--arch/arm/kernel/suspend.c4
-rw-r--r--arch/arm/kvm/Kconfig3
-rw-r--r--arch/arm/kvm/Makefile1
-rw-r--r--arch/arm/kvm/arm.c68
-rw-r--r--arch/arm/kvm/coproc.c70
-rw-r--r--arch/arm/kvm/coproc.h6
-rw-r--r--arch/arm/kvm/coproc_a15.c2
-rw-r--r--arch/arm/kvm/coproc_a7.c2
-rw-r--r--arch/arm/kvm/handle_exit.c8
-rw-r--r--arch/arm/kvm/interrupts.S11
-rw-r--r--arch/arm/kvm/mmu.c435
-rw-r--r--arch/arm/kvm/psci.c17
-rw-r--r--arch/arm/kvm/trace.h50
-rw-r--r--arch/arm/lib/Makefile15
-rw-r--r--arch/arm/lib/uaccess.S564
-rw-r--r--arch/arm/mach-at91/Kconfig120
-rw-r--r--arch/arm/mach-at91/Makefile20
-rw-r--r--arch/arm/mach-at91/at91rm9200.c66
-rw-r--r--arch/arm/mach-at91/at91sam9.c87
-rw-r--r--arch/arm/mach-at91/at91sam9260.c61
-rw-r--r--arch/arm/mach-at91/at91sam9261.c42
-rw-r--r--arch/arm/mach-at91/at91sam9263.c40
-rw-r--r--arch/arm/mach-at91/at91sam9g45.c40
-rw-r--r--arch/arm/mach-at91/at91sam9n12.c32
-rw-r--r--arch/arm/mach-at91/at91sam9rl.c53
-rw-r--r--arch/arm/mach-at91/at91sam9x5.c36
-rw-r--r--arch/arm/mach-at91/board-dt-rm9200.c43
-rw-r--r--arch/arm/mach-at91/board-dt-sam9.c36
-rw-r--r--arch/arm/mach-at91/board-dt-sama5.c59
-rw-r--r--arch/arm/mach-at91/generic.h26
-rw-r--r--arch/arm/mach-at91/include/mach/at91_pio.h80
-rw-r--r--arch/arm/mach-at91/include/mach/at91_rtt.h35
-rw-r--r--arch/arm/mach-at91/include/mach/cpu.h52
-rw-r--r--arch/arm/mach-at91/include/mach/memory.h26
-rw-r--r--arch/arm/mach-at91/include/mach/system_rev.h27
-rw-r--r--arch/arm/mach-at91/pm.c160
-rw-r--r--arch/arm/mach-at91/pm_slowclock.S9
-rw-r--r--arch/arm/mach-at91/sama5.c111
-rw-r--r--arch/arm/mach-at91/sama5d3.c41
-rw-r--r--arch/arm/mach-at91/sama5d4.c64
-rw-r--r--arch/arm/mach-at91/setup.c115
-rw-r--r--arch/arm/mach-at91/soc.h77
-rw-r--r--arch/arm/mach-at91/sysirq_mask.c75
-rw-r--r--arch/arm/mach-bcm/platsmp-brcmstb.c85
-rw-r--r--arch/arm/mach-cns3xxx/pcie.c92
-rw-r--r--arch/arm/mach-davinci/Makefile2
-rw-r--r--arch/arm/mach-davinci/board-dm646x-evm.c31
-rw-r--r--arch/arm/mach-davinci/cdce949.c295
-rw-r--r--arch/arm/mach-davinci/include/mach/cdce949.h19
-rw-r--r--arch/arm/mach-davinci/serial.c10
-rw-r--r--arch/arm/mach-digicolor/Kconfig7
-rw-r--r--arch/arm/mach-digicolor/Makefile1
-rw-r--r--arch/arm/mach-digicolor/digicolor.c18
-rw-r--r--arch/arm/mach-exynos/exynos.c40
-rw-r--r--arch/arm/mach-exynos/firmware.c50
-rw-r--r--arch/arm/mach-exynos/include/mach/dma.h26
-rw-r--r--arch/arm/mach-exynos/include/mach/map.h3
-rw-r--r--arch/arm/mach-exynos/pm.c3
-rw-r--r--arch/arm/mach-exynos/regs-pmu.h3
-rw-r--r--arch/arm/mach-exynos/regs-sys.h22
-rw-r--r--arch/arm/mach-exynos/sleep.S46
-rw-r--r--arch/arm/mach-exynos/suspend.c84
-rw-r--r--arch/arm/mach-hisi/Kconfig8
-rw-r--r--arch/arm/mach-hisi/core.h5
-rw-r--r--arch/arm/mach-hisi/headsmp.S2
-rw-r--r--arch/arm/mach-hisi/hisilicon.c10
-rw-r--r--arch/arm/mach-hisi/hotplug.c31
-rw-r--r--arch/arm/mach-hisi/platsmp.c56
-rw-r--r--arch/arm/mach-imx/clk-imx6q.c4
-rw-r--r--arch/arm/mach-imx/clk-imx6sx.c3
-rw-r--r--arch/arm/mach-imx/mach-imx6q.c2
-rw-r--r--arch/arm/mach-integrator/pci_v3.c62
-rw-r--r--arch/arm/mach-ks8695/pci.c77
-rw-r--r--arch/arm/mach-mediatek/Kconfig22
-rw-r--r--arch/arm/mach-mvebu/coherency.c58
-rw-r--r--arch/arm/mach-mvebu/mvebu-soc-id.h18
-rw-r--r--arch/arm/mach-omap1/include/mach/debug-macro.S101
-rw-r--r--arch/arm/mach-omap1/irq.c5
-rw-r--r--arch/arm/mach-omap1/timer32k.c5
-rw-r--r--arch/arm/mach-omap2/Kconfig12
-rw-r--r--arch/arm/mach-omap2/Makefile14
-rw-r--r--arch/arm/mach-omap2/am35xx-emac.c114
-rw-r--r--arch/arm/mach-omap2/am35xx-emac.h15
-rw-r--r--arch/arm/mach-omap2/am35xx.h46
-rw-r--r--arch/arm/mach-omap2/board-am3517crane.c150
-rw-r--r--arch/arm/mach-omap2/board-am3517evm.c373
-rw-r--r--arch/arm/mach-omap2/board-cm-t3517.c335
-rw-r--r--arch/arm/mach-omap2/board-generic.c60
-rw-r--r--arch/arm/mach-omap2/board-omap3pandora.c14
-rw-r--r--arch/arm/mach-omap2/cclock3xxx_data.c6
-rw-r--r--arch/arm/mach-omap2/clkt2xxx_apll.c142
-rw-r--r--arch/arm/mach-omap2/clock.c3
-rw-r--r--arch/arm/mach-omap2/clock.h1
-rw-r--r--arch/arm/mach-omap2/clock2xxx.h11
-rw-r--r--arch/arm/mach-omap2/clockdomain.h1
-rw-r--r--arch/arm/mach-omap2/clockdomains81xx_data.c194
-rw-r--r--arch/arm/mach-omap2/cm2xxx.c10
-rw-r--r--arch/arm/mach-omap2/cm2xxx.h2
-rw-r--r--arch/arm/mach-omap2/cm33xx.c21
-rw-r--r--arch/arm/mach-omap2/cm81xx.h61
-rw-r--r--arch/arm/mach-omap2/common.h21
-rw-r--r--arch/arm/mach-omap2/control.h8
-rw-r--r--arch/arm/mach-omap2/dpll44xx.c20
-rw-r--r--arch/arm/mach-omap2/id.c2
-rw-r--r--arch/arm/mach-omap2/io.c66
-rw-r--r--arch/arm/mach-omap2/omap-headsmp.S21
-rw-r--r--arch/arm/mach-omap2/omap-pm-noop.c196
-rw-r--r--arch/arm/mach-omap2/omap-pm.h192
-rw-r--r--arch/arm/mach-omap2/omap-smp.c13
-rw-r--r--arch/arm/mach-omap2/omap4-common.c48
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c248
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.h18
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_3xxx_data.c33
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_43xx_data.c2
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_44xx_data.c5
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_54xx_data.c1
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_7xx_data.c5
-rw-r--r--arch/arm/mach-omap2/omap_hwmod_81xx_data.c1136
-rw-r--r--arch/arm/mach-omap2/omap_phy_internal.c35
-rw-r--r--arch/arm/mach-omap2/pdata-quirks.c1
-rw-r--r--arch/arm/mach-omap2/pmu.c5
-rw-r--r--arch/arm/mach-omap2/powerdomain.c82
-rw-r--r--arch/arm/mach-omap2/powerdomain.h5
-rw-r--r--arch/arm/mach-omap2/powerdomains3xxx_data.c2
-rw-r--r--arch/arm/mach-omap2/prcm-common.h1
-rw-r--r--arch/arm/mach-omap2/prm3xxx.h1
-rw-r--r--arch/arm/mach-omap2/prm44xx.c5
-rw-r--r--arch/arm/mach-omap2/prm44xx_54xx.h1
-rw-r--r--arch/arm/mach-omap2/prm_common.c18
-rw-r--r--arch/arm/mach-omap2/soc.h4
-rw-r--r--arch/arm/mach-omap2/ti81xx-restart.c34
-rw-r--r--arch/arm/mach-omap2/timer.c46
-rw-r--r--arch/arm/mach-omap2/twl-common.c7
-rw-r--r--arch/arm/mach-omap2/usb-musb.c12
-rw-r--r--arch/arm/mach-omap2/usb.h2
-rw-r--r--arch/arm/mach-omap2/voltage.c110
-rw-r--r--arch/arm/mach-omap2/voltage.h13
-rw-r--r--arch/arm/mach-prima2/Kconfig22
-rw-r--r--arch/arm/mach-prima2/Makefile1
-rw-r--r--arch/arm/mach-prima2/common.c22
-rw-r--r--arch/arm/mach-prima2/common.h15
-rw-r--r--arch/arm/mach-prima2/lluart.c35
-rw-r--r--arch/arm/mach-prima2/platsmp.c52
-rw-r--r--arch/arm/mach-prima2/rstc.c41
-rw-r--r--arch/arm/mach-prima2/rtciobrg.c1
-rw-r--r--arch/arm/mach-pxa/Kconfig6
-rw-r--r--arch/arm/mach-pxa/corgi.c3
-rw-r--r--arch/arm/mach-pxa/devices.c2
-rw-r--r--arch/arm/mach-pxa/hx4700.c2
-rw-r--r--arch/arm/mach-pxa/include/mach/irqs.h10
-rw-r--r--arch/arm/mach-pxa/poodle.c2
-rw-r--r--arch/arm/mach-pxa/spitz.c2
-rw-r--r--arch/arm/mach-qcom/Kconfig3
-rw-r--r--arch/arm/mach-qcom/platsmp.c4
-rw-r--r--arch/arm/mach-qcom/scm-boot.c10
-rw-r--r--arch/arm/mach-qcom/scm-boot.h4
-rw-r--r--arch/arm/mach-qcom/scm.c85
-rw-r--r--arch/arm/mach-realview/realview_eb.c3
-rw-r--r--arch/arm/mach-realview/realview_pb1176.c2
-rw-r--r--arch/arm/mach-realview/realview_pb11mp.c2
-rw-r--r--arch/arm/mach-realview/realview_pba8.c2
-rw-r--r--arch/arm/mach-realview/realview_pbx.c2
-rw-r--r--arch/arm/mach-rockchip/Kconfig1
-rw-r--r--arch/arm/mach-rockchip/Makefile1
-rw-r--r--arch/arm/mach-rockchip/pm.c260
-rw-r--r--arch/arm/mach-rockchip/pm.h99
-rw-r--r--arch/arm/mach-rockchip/rockchip.c31
-rw-r--r--arch/arm/mach-rockchip/sleep.S73
-rw-r--r--arch/arm/mach-s3c24xx/Kconfig42
-rw-r--r--arch/arm/mach-s3c24xx/Makefile7
-rw-r--r--arch/arm/mach-s3c24xx/dma-s3c2410.c182
-rw-r--r--arch/arm/mach-s3c24xx/dma-s3c2412.c150
-rw-r--r--arch/arm/mach-s3c24xx/dma-s3c2440.c193
-rw-r--r--arch/arm/mach-s3c24xx/dma-s3c2443.c179
-rw-r--r--arch/arm/mach-s3c24xx/dma.c1465
-rw-r--r--arch/arm/mach-s3c24xx/include/mach/dma.h159
-rw-r--r--arch/arm/mach-s3c64xx/include/mach/dma.h15
-rw-r--r--arch/arm/mach-sa1100/Makefile2
-rw-r--r--arch/arm/mach-sa1100/assabet.c2
-rw-r--r--arch/arm/mach-sa1100/clock.c12
-rw-r--r--arch/arm/mach-sa1100/collie.c5
-rw-r--r--arch/arm/mach-sa1100/generic.c6
-rw-r--r--arch/arm/mach-sa1100/h3100.c2
-rw-r--r--arch/arm/mach-sa1100/h3600.c2
-rw-r--r--arch/arm/mach-sa1100/include/mach/irqs.h73
-rw-r--r--arch/arm/mach-sa1100/irq.c203
-rw-r--r--arch/arm/mach-sa1100/pci-nanoengine.c94
-rw-r--r--arch/arm/mach-sa1100/pm.c1
-rw-r--r--arch/arm/mach-sa1100/time.c139
-rw-r--r--arch/arm/mach-shmobile/Kconfig28
-rw-r--r--arch/arm/mach-shmobile/Makefile3
-rw-r--r--arch/arm/mach-shmobile/Makefile.boot1
-rw-r--r--arch/arm/mach-shmobile/board-ape6evm.c20
-rw-r--r--arch/arm/mach-shmobile/board-lager-reference.c39
-rw-r--r--arch/arm/mach-shmobile/board-lager.c827
-rw-r--r--arch/arm/mach-shmobile/clock-r8a7790.c459
-rw-r--r--arch/arm/mach-shmobile/clock-sh73a0.c10
-rw-r--r--arch/arm/mach-shmobile/pm-r8a7740.c14
-rw-r--r--arch/arm/mach-shmobile/pm-rmobile.c314
-rw-r--r--arch/arm/mach-shmobile/pm-rmobile.h3
-rw-r--r--arch/arm/mach-shmobile/pm-sh7372.c11
-rw-r--r--arch/arm/mach-shmobile/r8a7790.h28
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7740.c9
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7778.c9
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7779.c9
-rw-r--r--arch/arm/mach-shmobile/setup-r8a7790.c284
-rw-r--r--arch/arm/mach-shmobile/setup-rcar-gen2.c6
-rw-r--r--arch/arm/mach-shmobile/setup-sh73a0.c5
-rw-r--r--arch/arm/mach-shmobile/smp-r8a7779.c2
-rw-r--r--arch/arm/mach-shmobile/timer.c12
-rw-r--r--arch/arm/mach-sti/board-dt.c1
-rw-r--r--arch/arm/mach-sunxi/platsmp.c2
-rw-r--r--arch/arm/mach-sunxi/sunxi.c11
-rw-r--r--arch/arm/mach-tegra/Kconfig4
-rw-r--r--arch/arm/mach-versatile/core.c37
-rw-r--r--arch/arm/mach-zynq/Kconfig2
-rw-r--r--arch/arm/mach-zynq/common.c2
-rw-r--r--arch/arm/mach-zynq/pm.c2
-rw-r--r--arch/arm/mach-zynq/slcr.c35
-rw-r--r--arch/arm/mm/Kconfig1
-rw-r--r--arch/arm/mm/cache-l2x0.c443
-rw-r--r--arch/arm/mm/context.c26
-rw-r--r--arch/arm/mm/dma-mapping.c56
-rw-r--r--arch/arm/mm/hugetlbpage.c6
-rw-r--r--arch/arm/mm/init.c5
-rw-r--r--arch/arm/mm/pgd.c4
-rw-r--r--arch/arm/mm/proc-macros.S2
-rw-r--r--arch/arm/plat-iop/pmu.c2
-rw-r--r--arch/arm/plat-omap/dma.c8
-rw-r--r--arch/arm/plat-samsung/Kconfig15
-rw-r--r--arch/arm/plat-samsung/Makefile6
-rw-r--r--arch/arm/plat-samsung/cpu.c4
-rw-r--r--arch/arm/plat-samsung/dma-ops.c146
-rw-r--r--arch/arm/plat-samsung/dma.c84
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-core.h22
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-ops.h69
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-pl330.h121
-rw-r--r--arch/arm/plat-samsung/include/plat/dma-s3c24xx.h73
-rw-r--r--arch/arm/plat-samsung/include/plat/dma.h130
-rw-r--r--arch/arm/plat-samsung/include/plat/regs-dma.h151
-rw-r--r--arch/arm/plat-samsung/s3c-dma-ops.c146
-rw-r--r--arch/arm/probes/Makefile7
-rw-r--r--arch/arm/probes/decode-arm.c (renamed from arch/arm/kernel/probes-arm.c)18
-rw-r--r--arch/arm/probes/decode-arm.h (renamed from arch/arm/kernel/probes-arm.h)9
-rw-r--r--arch/arm/probes/decode-thumb.c (renamed from arch/arm/kernel/probes-thumb.c)16
-rw-r--r--arch/arm/probes/decode-thumb.h (renamed from arch/arm/kernel/probes-thumb.h)10
-rw-r--r--arch/arm/probes/decode.c (renamed from arch/arm/kernel/probes.c)81
-rw-r--r--arch/arm/probes/decode.h (renamed from arch/arm/kernel/probes.h)13
-rw-r--r--arch/arm/probes/kprobes/Makefile12
-rw-r--r--arch/arm/probes/kprobes/actions-arm.c (renamed from arch/arm/kernel/kprobes-arm.c)11
-rw-r--r--arch/arm/probes/kprobes/actions-common.c (renamed from arch/arm/kernel/kprobes-common.c)4
-rw-r--r--arch/arm/probes/kprobes/actions-thumb.c (renamed from arch/arm/kernel/kprobes-thumb.c)10
-rw-r--r--arch/arm/probes/kprobes/checkers-arm.c192
-rw-r--r--arch/arm/probes/kprobes/checkers-common.c101
-rw-r--r--arch/arm/probes/kprobes/checkers-thumb.c110
-rw-r--r--arch/arm/probes/kprobes/checkers.h55
-rw-r--r--arch/arm/probes/kprobes/core.c (renamed from arch/arm/kernel/kprobes.c)49
-rw-r--r--arch/arm/probes/kprobes/core.h (renamed from arch/arm/kernel/kprobes.h)12
-rw-r--r--arch/arm/probes/kprobes/opt-arm.c370
-rw-r--r--arch/arm/probes/kprobes/test-arm.c (renamed from arch/arm/kernel/kprobes-test-arm.c)40
-rw-r--r--arch/arm/probes/kprobes/test-core.c (renamed from arch/arm/kernel/kprobes-test.c)46
-rw-r--r--arch/arm/probes/kprobes/test-core.h (renamed from arch/arm/kernel/kprobes-test.h)35
-rw-r--r--arch/arm/probes/kprobes/test-thumb.c (renamed from arch/arm/kernel/kprobes-test-thumb.c)20
-rw-r--r--arch/arm/probes/uprobes/Makefile1
-rw-r--r--arch/arm/probes/uprobes/actions-arm.c (renamed from arch/arm/kernel/uprobes-arm.c)8
-rw-r--r--arch/arm/probes/uprobes/core.c (renamed from arch/arm/kernel/uprobes.c)8
-rw-r--r--arch/arm/probes/uprobes/core.h (renamed from arch/arm/kernel/uprobes.h)0
-rw-r--r--arch/arm/xen/enlighten.c4
-rw-r--r--arch/arm/xen/mm.c2
-rw-r--r--arch/arm/xen/p2m.c2
397 files changed, 6752 insertions, 11690 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 97d07ed60a0b..9f1f09a2bc9b 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -29,6 +29,7 @@ config ARM
select HANDLE_DOMAIN_IRQ
select HARDIRQS_SW_RESEND
select HAVE_ARCH_AUDITSYSCALL if (AEABI && !OABI_COMPAT)
+ select HAVE_ARCH_BITREVERSE if (CPU_32v7M || CPU_32v7) && !CPU_32v6
select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
select HAVE_ARCH_KGDB
select HAVE_ARCH_SECCOMP_FILTER if (AEABI && !OABI_COMPAT)
@@ -60,6 +61,7 @@ config ARM
select HAVE_MEMBLOCK
select HAVE_MOD_ARCH_SPECIFIC if ARM_UNWIND
select HAVE_OPROFILE if (HAVE_PERF_EVENTS)
+ select HAVE_OPTPROBES if !THUMB2_KERNEL
select HAVE_PERF_EVENTS
select HAVE_PERF_REGS
select HAVE_PERF_USER_STACK_DUMP
@@ -858,6 +860,8 @@ source "arch/arm/mach-cns3xxx/Kconfig"
source "arch/arm/mach-davinci/Kconfig"
+source "arch/arm/mach-digicolor/Kconfig"
+
source "arch/arm/mach-dove/Kconfig"
source "arch/arm/mach-ep93xx/Kconfig"
@@ -1279,6 +1283,9 @@ config PCI_DOMAINS
bool
depends on PCI
+config PCI_DOMAINS_GENERIC
+ def_bool PCI_DOMAINS
+
config PCI_NANOENGINE
bool "BSE nanoEngine PCI support"
depends on SA1100_NANOENGINE
@@ -1488,7 +1495,7 @@ config ARM_PSCI
# selected platforms.
config ARCH_NR_GPIO
int
- default 1024 if ARCH_SHMOBILE || ARCH_TEGRA
+ default 1024 if ARCH_SHMOBILE || ARCH_TEGRA || ARCH_ZYNQ
default 512 if ARCH_EXYNOS || ARCH_KEYSTONE || SOC_OMAP5 || \
SOC_DRA7XX || ARCH_S3C24XX || ARCH_S3C64XX || ARCH_S5PV210
default 416 if ARCH_SUNXI
diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug
index 5ddd4906f7a7..970de7518341 100644
--- a/arch/arm/Kconfig.debug
+++ b/arch/arm/Kconfig.debug
@@ -115,16 +115,22 @@ choice
0x80024000 | 0xf0024000 | UART9
config AT91_DEBUG_LL_DBGU0
- bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10 and 9rl"
- depends on HAVE_AT91_DBGU0
+ bool "Kernel low-level debugging on rm9200, 9260/9g20, 9261/9g10, 9rl, 9x5, 9n12"
+ select DEBUG_AT91_UART
+ depends on ARCH_AT91
+ depends on SOC_AT91RM9200 || SOC_AT91SAM9
config AT91_DEBUG_LL_DBGU1
- bool "Kernel low-level debugging on 9263 and 9g45"
- depends on HAVE_AT91_DBGU1
+ bool "Kernel low-level debugging on 9263, 9g45 and sama5d3"
+ select DEBUG_AT91_UART
+ depends on ARCH_AT91
+ depends on SOC_AT91SAM9 || SOC_SAMA5
config AT91_DEBUG_LL_DBGU2
bool "Kernel low-level debugging on sama5d4"
- depends on HAVE_AT91_DBGU2
+ select DEBUG_AT91_UART
+ depends on ARCH_AT91
+ depends on SOC_SAMA5
config DEBUG_BCM2835
bool "Kernel low-level debugging on BCM2835 PL011 UART"
@@ -241,6 +247,13 @@ choice
Say Y here if you want the debug print routines to direct
their output to the serial port in the DC21285 (Footbridge).
+ config DEBUG_DIGICOLOR_UA0
+ bool "Kernel low-level debugging messages via Digicolor UA0"
+ depends on ARCH_DIGICOLOR
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the UA0 serial port in the CX92755.
+
config DEBUG_FOOTBRIDGE_COM1
bool "Kernel low-level debugging messages via footbridge 8250 at PCI COM1"
depends on FOOTBRIDGE
@@ -272,6 +285,14 @@ choice
Say Y here if you want the debug print routines to direct
their output to the UART on Highbank based devices.
+ config DEBUG_HIP01_UART
+ bool "Hisilicon Hip01 Debug UART"
+ depends on ARCH_HIP01
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on HIP01 UART.
+
config DEBUG_HIP04_UART
bool "Hisilicon HiP04 Debug UART"
depends on ARCH_HIP04
@@ -397,6 +418,13 @@ choice
Say Y here if you want the debug print routines to direct
their output to UART1 serial port on KEYSTONE2 devices.
+ config DEBUG_KS8695_UART
+ bool "KS8695 Debug UART"
+ depends on ARCH_KS8695
+ help
+ Say Y here if you want kernel low-level debugging support
+ on KS8695.
+
config DEBUG_MESON_UARTAO
bool "Kernel low-level debugging via Meson6 UARTAO"
depends on ARCH_MESON
@@ -427,7 +455,7 @@ choice
Say Y here if you want the debug print routines to direct
their output to the serial port on MSM devices.
- ARCH DEBUG_UART_PHYS DEBUG_UART_BASE #
+ ARCH DEBUG_UART_PHYS DEBUG_UART_VIRT #
MSM7X00A, QSD8X50 0xa9a00000 0xe1000000 UART1
MSM7X00A, QSD8X50 0xa9b00000 0xe1000000 UART2
MSM7X00A, QSD8X50 0xa9c00000 0xe1000000 UART3
@@ -446,7 +474,8 @@ choice
Say Y here if you want the debug print routines to direct
their output to the serial port on Qualcomm devices.
- ARCH DEBUG_UART_PHYS DEBUG_UART_BASE
+ ARCH DEBUG_UART_PHYS DEBUG_UART_VIRT
+ APQ8064 0x16640000 0xf0040000
APQ8084 0xf995e000 0xfa75e000
MSM8X60 0x19c40000 0xf0040000
MSM8960 0x16440000 0xf0040000
@@ -455,13 +484,13 @@ choice
Please adjust DEBUG_UART_PHYS and DEBUG_UART_BASE configuration
options based on your needs.
- config DEBUG_MVEBU_UART
- bool "Kernel low-level debugging messages via MVEBU UART (old bootloaders)"
+ config DEBUG_MVEBU_UART0
+ bool "Kernel low-level debugging messages via MVEBU UART0 (old bootloaders)"
depends on ARCH_MVEBU
select DEBUG_UART_8250
help
Say Y here if you want kernel low-level debugging support
- on MVEBU based platforms.
+ on MVEBU based platforms on UART0.
This option should be used with the old bootloaders
that left the internal registers mapped at
@@ -474,13 +503,28 @@ choice
when u-boot hands over to the kernel, the system
silently crashes, with no serial output at all.
- config DEBUG_MVEBU_UART_ALTERNATE
- bool "Kernel low-level debugging messages via MVEBU UART (new bootloaders)"
+ config DEBUG_MVEBU_UART0_ALTERNATE
+ bool "Kernel low-level debugging messages via MVEBU UART0 (new bootloaders)"
depends on ARCH_MVEBU
select DEBUG_UART_8250
help
Say Y here if you want kernel low-level debugging support
- on MVEBU based platforms.
+ on MVEBU based platforms on UART0.
+
+ This option should be used with the new bootloaders
+ that remap the internal registers at 0xf1000000.
+
+ If the wrong DEBUG_MVEBU_UART* option is selected,
+ when u-boot hands over to the kernel, the system
+ silently crashes, with no serial output at all.
+
+ config DEBUG_MVEBU_UART1_ALTERNATE
+ bool "Kernel low-level debugging messages via MVEBU UART1 (new bootloaders)"
+ depends on ARCH_MVEBU
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on MVEBU based platforms on UART1.
This option should be used with the new bootloaders
that remap the internal registers at 0xf1000000.
@@ -496,6 +540,13 @@ choice
Say Y here if you want kernel low-level debugging support
on Vybrid based platforms.
+ config DEBUG_NETX_UART
+ bool "Kernel low-level debugging messages via NetX UART"
+ depends on ARCH_NETX
+ help
+ Say Y here if you want kernel low-level debugging support
+ on Hilscher NetX based platforms.
+
config DEBUG_NOMADIK_UART
bool "Kernel low-level debugging messages via NOMADIK UART"
depends on ARCH_NOMADIK
@@ -520,6 +571,30 @@ choice
Say Y here if you want kernel low-level debugging support
on TI-NSPIRE CX models.
+ config DEBUG_OMAP1UART1
+ bool "Kernel low-level debugging via OMAP1 UART1"
+ depends on ARCH_OMAP1
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on OMAP1 based platforms (except OMAP730) on the UART1.
+
+ config DEBUG_OMAP1UART2
+ bool "Kernel low-level debugging via OMAP1 UART2"
+ depends on ARCH_OMAP1
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on OMAP1 based platforms (except OMAP730) on the UART2.
+
+ config DEBUG_OMAP1UART3
+ bool "Kernel low-level debugging via OMAP1 UART3"
+ depends on ARCH_OMAP1
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on OMAP1 based platforms (except OMAP730) on the UART3.
+
config DEBUG_OMAP2UART1
bool "OMAP2/3/4 UART1 (omap2/3 sdp boards and some omap3 boards)"
depends on ARCH_OMAP2PLUS
@@ -562,6 +637,30 @@ choice
depends on ARCH_OMAP2PLUS
select DEBUG_OMAP2PLUS_UART
+ config DEBUG_OMAP7XXUART1
+ bool "Kernel low-level debugging via OMAP730 UART1"
+ depends on ARCH_OMAP730
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on OMAP730 based platforms on the UART1.
+
+ config DEBUG_OMAP7XXUART2
+ bool "Kernel low-level debugging via OMAP730 UART2"
+ depends on ARCH_OMAP730
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on OMAP730 based platforms on the UART2.
+
+ config DEBUG_OMAP7XXUART3
+ bool "Kernel low-level debugging via OMAP730 UART3"
+ depends on ARCH_OMAP730
+ select DEBUG_UART_8250
+ help
+ Say Y here if you want kernel low-level debugging support
+ on OMAP730 based platforms on the UART3.
+
config DEBUG_TI81XXUART1
bool "Kernel low-level debugging messages via TI81XX UART1 (ti8148evm)"
depends on ARCH_OMAP2PLUS
@@ -916,16 +1015,28 @@ choice
config DEBUG_SIRFPRIMA2_UART1
bool "Kernel low-level debugging messages via SiRFprimaII UART1"
depends on ARCH_PRIMA2
+ select DEBUG_SIRFSOC_UART
help
Say Y here if you want the debug print routines to direct
their output to the uart1 port on SiRFprimaII devices.
- config DEBUG_SIRFMARCO_UART1
- bool "Kernel low-level debugging messages via SiRFmarco UART1"
- depends on ARCH_MARCO
+ config DEBUG_SIRFATLAS7_UART0
+ bool "Kernel low-level debugging messages via SiRFatlas7 UART0"
+ depends on ARCH_ATLAS7
+ select DEBUG_SIRFSOC_UART
+ help
+ Say Y here if you want the debug print routines to direct
+ their output to the uart0 port on SiRFATLAS7 devices.The uart0
+ is used on SiRFATLAS7 as a extra debug port.sometimes an extra
+ debug port can be very useful.
+
+ config DEBUG_SIRFATLAS7_UART1
+ bool "Kernel low-level debugging messages via SiRFatlas7 UART1"
+ depends on ARCH_ATLAS7
+ select DEBUG_SIRFSOC_UART
help
Say Y here if you want the debug print routines to direct
- their output to the uart1 port on SiRFmarco devices.
+ their output to the uart1 port on SiRFATLAS7 devices.
config STIH41X_DEBUG_ASC2
bool "Use StiH415/416 ASC2 UART for low-level debug"
@@ -973,7 +1084,7 @@ choice
for Mediatek mt6589 based platforms on UART0.
config DEBUG_MT8127_UART0
- bool "Mediatek mt8127 UART0"
+ bool "Mediatek mt8127/mt6592 UART0"
depends on ARCH_MEDIATEK
select DEBUG_UART_8250
help
@@ -1031,15 +1142,6 @@ choice
This option selects UART0 on VIA/Wondermedia System-on-a-chip
devices, including VT8500, WM8505, WM8650 and WM8850.
- config DEBUG_LL_UART_NONE
- bool "No low-level debugging UART"
- depends on !ARCH_MULTIPLATFORM
- help
- Say Y here if your platform doesn't provide a UART option
- above. This relies on your platform choosing the right UART
- definition internally in order for low-level debugging to
- work.
-
config DEBUG_ICEDCC
bool "Kernel low-level debugging via EmbeddedICE DCC channel"
help
@@ -1109,6 +1211,10 @@ choice
endchoice
+config DEBUG_AT91_UART
+ bool
+ depends on ARCH_AT91
+
config DEBUG_EXYNOS_UART
bool
@@ -1161,10 +1267,15 @@ config DEBUG_STI_UART
bool
depends on ARCH_STI
+config DEBUG_SIRFSOC_UART
+ bool
+ depends on ARCH_SIRF
+
config DEBUG_LL_INCLUDE
string
default "debug/sa1100.S" if DEBUG_SA1100
default "debug/8250.S" if DEBUG_LL_UART_8250 || DEBUG_UART_8250
+ default "debug/at91.S" if DEBUG_AT91_UART
default "debug/asm9260.S" if DEBUG_ASM9260_UART
default "debug/clps711x.S" if DEBUG_CLPS711X_UART1 || DEBUG_CLPS711X_UART2
default "debug/meson.S" if DEBUG_MESON_UARTAO
@@ -1183,7 +1294,9 @@ config DEBUG_LL_INCLUDE
DEBUG_IMX6Q_UART || \
DEBUG_IMX6SL_UART || \
DEBUG_IMX6SX_UART
+ default "debug/ks8695.S" if DEBUG_KS8695_UART
default "debug/msm.S" if DEBUG_MSM_UART || DEBUG_QCOM_UARTDM
+ default "debug/netx.S" if DEBUG_NETX_UART
default "debug/omap2plus.S" if DEBUG_OMAP2PLUS_UART
default "debug/renesas-scif.S" if DEBUG_R7S72100_SCIF2
default "debug/renesas-scif.S" if DEBUG_RCAR_GEN1_SCIF0
@@ -1195,7 +1308,7 @@ config DEBUG_LL_INCLUDE
default "debug/renesas-scif.S" if DEBUG_RMOBILE_SCIFA4
default "debug/s3c24xx.S" if DEBUG_S3C24XX_UART
default "debug/s5pv210.S" if DEBUG_S5PV210_UART
- default "debug/sirf.S" if DEBUG_SIRFPRIMA2_UART1 || DEBUG_SIRFMARCO_UART1
+ default "debug/sirf.S" if DEBUG_SIRFSOC_UART
default "debug/sti.S" if DEBUG_STI_UART
default "debug/tegra.S" if DEBUG_TEGRA_UART
default "debug/ux500.S" if DEBUG_UX500_UART
@@ -1204,16 +1317,12 @@ config DEBUG_LL_INCLUDE
default "debug/vt8500.S" if DEBUG_VT8500_UART0
default "debug/zynq.S" if DEBUG_ZYNQ_UART0 || DEBUG_ZYNQ_UART1
default "debug/bcm63xx.S" if DEBUG_UART_BCM63XX
+ default "debug/digicolor.S" if DEBUG_DIGICOLOR_UA0
default "mach/debug-macro.S"
# Compatibility options for PL01x
config DEBUG_UART_PL01X
- def_bool ARCH_EP93XX || \
- ARCH_INTEGRATOR || \
- ARCH_SPEAR3XX || \
- ARCH_SPEAR6XX || \
- ARCH_SPEAR13XX || \
- ARCH_VERSATILE
+ bool
# Compatibility options for 8250
config DEBUG_UART_8250
@@ -1229,6 +1338,7 @@ config DEBUG_UART_BCM63XX
config DEBUG_UART_PHYS
hex "Physical base address of debug UART"
+ default 0x00100a00 if DEBUG_NETX_UART
default 0x01c20000 if DEBUG_DAVINCI_DMx_UART0
default 0x01c28000 if DEBUG_SUNXI_UART0
default 0x01c28400 if DEBUG_SUNXI_UART1
@@ -1251,7 +1361,10 @@ config DEBUG_UART_PHYS
default 0x11009000 if DEBUG_MT8135_UART3
default 0x16000000 if ARCH_INTEGRATOR
default 0x18000300 if DEBUG_BCM_5301X
+ default 0x18010000 if DEBUG_SIRFATLAS7_UART0
+ default 0x18020000 if DEBUG_SIRFATLAS7_UART1
default 0x1c090000 if DEBUG_VEXPRESS_UART0_RS1
+ default 0x20001000 if DEBUG_HIP01_UART
default 0x20060000 if DEBUG_RK29_UART0
default 0x20064000 if DEBUG_RK29_UART1 || DEBUG_RK3X_UART2
default 0x20068000 if DEBUG_RK29_UART2 || DEBUG_RK3X_UART3
@@ -1269,7 +1382,6 @@ config DEBUG_UART_PHYS
DEBUG_S3C2410_UART2)
default 0x78000000 if DEBUG_CNS3XXX
default 0x7c0003f8 if FOOTBRIDGE
- default 0x78000000 if DEBUG_CNS3XXX
default 0x80010000 if DEBUG_ASM9260_UART
default 0x80070000 if DEBUG_IMX23_UART
default 0x80074000 if DEBUG_IMX28_UART
@@ -1277,12 +1389,13 @@ config DEBUG_UART_PHYS
default 0x808c0000 if ARCH_EP93XX
default 0x90020000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART
default 0xa9a00000 if DEBUG_MSM_UART
+ default 0xb0060000 if DEBUG_SIRFPRIMA2_UART1
default 0xb0090000 if DEBUG_VEXPRESS_UART0_CRX
default 0xc0013000 if DEBUG_U300_UART
default 0xc8000000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN
default 0xc8000003 if ARCH_IXP4XX && CPU_BIG_ENDIAN
default 0xd0000000 if ARCH_SPEAR3XX || ARCH_SPEAR6XX
- default 0xd0012000 if DEBUG_MVEBU_UART
+ default 0xd0012000 if DEBUG_MVEBU_UART0
default 0xc81004c0 if DEBUG_MESON_UARTAO
default 0xd4017000 if DEBUG_MMP_UART2
default 0xd4018000 if DEBUG_MMP_UART3
@@ -1296,7 +1409,8 @@ config DEBUG_UART_PHYS
default 0xe8008000 if DEBUG_R7S72100_SCIF2
default 0xf0000be0 if ARCH_EBSA110
default 0xf040ab00 if DEBUG_BRCMSTB_UART
- default 0xf1012000 if DEBUG_MVEBU_UART_ALTERNATE
+ default 0xf1012000 if DEBUG_MVEBU_UART0_ALTERNATE
+ default 0xf1012100 if DEBUG_MVEBU_UART1_ALTERNATE
default 0xf1012000 if ARCH_DOVE || ARCH_MV78XX0 || \
ARCH_ORION5X
default 0xf7fc9000 if DEBUG_BERLIN_UART
@@ -1310,20 +1424,27 @@ config DEBUG_UART_PHYS
default 0xffe40000 if DEBUG_RCAR_GEN1_SCIF0
default 0xffe42000 if DEBUG_RCAR_GEN1_SCIF2
default 0xfff36000 if DEBUG_HIGHBANK_UART
+ default 0xfffb0000 if DEBUG_OMAP1UART1 || DEBUG_OMAP7XXUART1
+ default 0xfffb0800 if DEBUG_OMAP1UART2 || DEBUG_OMAP7XXUART2
+ default 0xfffb9800 if DEBUG_OMAP1UART3 || DEBUG_OMAP7XXUART3
default 0xfffe8600 if DEBUG_UART_BCM63XX
default 0xfffff700 if ARCH_IOP33X
- depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
+ depends on ARCH_EP93XX || \
+ DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
DEBUG_LL_UART_EFM32 || \
DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
- DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_R7S72100_SCIF2 || \
+ DEBUG_MSM_UART || DEBUG_NETX_UART || \
+ DEBUG_QCOM_UARTDM || DEBUG_R7S72100_SCIF2 || \
DEBUG_RCAR_GEN1_SCIF0 || DEBUG_RCAR_GEN1_SCIF2 || \
DEBUG_RCAR_GEN2_SCIF0 || DEBUG_RCAR_GEN2_SCIF2 || \
DEBUG_RMOBILE_SCIFA0 || DEBUG_RMOBILE_SCIFA1 || \
DEBUG_RMOBILE_SCIFA4 || DEBUG_S3C24XX_UART || \
- DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART
+ DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART || \
+ DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0
config DEBUG_UART_VIRT
hex "Virtual base address of debug UART"
+ default 0xe0000a00 if DEBUG_NETX_UART
default 0xe0010fe0 if ARCH_RPC
default 0xe1000000 if DEBUG_MSM_UART
default 0xf0000be0 if ARCH_EBSA110
@@ -1377,8 +1498,12 @@ config DEBUG_UART_VIRT
default 0xfeb30c00 if DEBUG_KEYSTONE_UART0
default 0xfeb31000 if DEBUG_KEYSTONE_UART1
default 0xfec02000 if DEBUG_SOCFPGA_UART
- default 0xfec12000 if DEBUG_MVEBU_UART || DEBUG_MVEBU_UART_ALTERNATE
+ default 0xfec12000 if DEBUG_MVEBU_UART0 || DEBUG_MVEBU_UART0_ALTERNATE
+ default 0xfec12100 if DEBUG_MVEBU_UART1_ALTERNATE
+ default 0xfec10000 if DEBUG_SIRFATLAS7_UART0
default 0xfec20000 if DEBUG_DAVINCI_DMx_UART0
+ default 0xfec20000 if DEBUG_SIRFATLAS7_UART1
+ default 0xfec60000 if DEBUG_SIRFPRIMA2_UART1
default 0xfec90000 if DEBUG_RK32_UART2
default 0xfed0c000 if DEBUG_DAVINCI_DA8XX_UART1
default 0xfed0d000 if DEBUG_DAVINCI_DA8XX_UART2
@@ -1392,18 +1517,25 @@ config DEBUG_UART_VIRT
default 0xfef00000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN
default 0xfef00003 if ARCH_IXP4XX && CPU_BIG_ENDIAN
default 0xfef36000 if DEBUG_HIGHBANK_UART
+ default 0xfefb0000 if DEBUG_OMAP1UART1 || DEBUG_OMAP7XXUART1
+ default 0xfefb0800 if DEBUG_OMAP1UART2 || DEBUG_OMAP7XXUART2
+ default 0xfefb9800 if DEBUG_OMAP1UART3 || DEBUG_OMAP7XXUART3
default 0xfefff700 if ARCH_IOP33X
default 0xff003000 if DEBUG_U300_UART
+ default 0xffd01000 if DEBUG_HIP01_UART
default DEBUG_UART_PHYS if !MMU
depends on DEBUG_LL_UART_8250 || DEBUG_LL_UART_PL01X || \
DEBUG_UART_8250 || DEBUG_UART_PL01X || DEBUG_MESON_UARTAO || \
- DEBUG_MSM_UART || DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \
- DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART
+ DEBUG_MSM_UART || DEBUG_NETX_UART || \
+ DEBUG_QCOM_UARTDM || DEBUG_S3C24XX_UART || \
+ DEBUG_UART_BCM63XX || DEBUG_ASM9260_UART || \
+ DEBUG_SIRFSOC_UART || DEBUG_DIGICOLOR_UA0
config DEBUG_UART_8250_SHIFT
int "Register offset shift for the 8250 debug UART"
depends on DEBUG_LL_UART_8250 || DEBUG_UART_8250
- default 0 if FOOTBRIDGE || ARCH_IOP32X || DEBUG_BCM_5301X
+ default 0 if FOOTBRIDGE || ARCH_IOP32X || DEBUG_BCM_5301X || \
+ DEBUG_OMAP7XXUART1 || DEBUG_OMAP7XXUART2 || DEBUG_OMAP7XXUART3
default 2
config DEBUG_UART_8250_WORD
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index c1785eec2cf7..7f99cd652203 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -266,6 +266,7 @@ core-$(CONFIG_KVM_ARM_HOST) += arch/arm/kvm/
# If we have a machine-specific directory, then include it in the build.
core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
+core-y += arch/arm/probes/
core-y += arch/arm/net/
core-y += arch/arm/crypto/
core-y += arch/arm/firmware/
diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S
index 68be9017593d..c41a793b519c 100644
--- a/arch/arm/boot/compressed/head.S
+++ b/arch/arm/boot/compressed/head.S
@@ -178,7 +178,7 @@ not_angel:
/*
* Set up a page table only if it won't overwrite ourself.
- * That means r4 < pc && r4 - 16k page directory > &_end.
+ * That means r4 < pc || r4 - 16k page directory > &_end.
* Given that r4 > &_end is most unfrequent, we add a rough
* additional 1MB of room for a possible appended DTB.
*/
@@ -263,16 +263,37 @@ restart: adr r0, LC0
* OK... Let's do some funky business here.
* If we do have a DTB appended to zImage, and we do have
* an ATAG list around, we want the later to be translated
- * and folded into the former here. To be on the safe side,
- * let's temporarily move the stack away into the malloc
- * area. No GOT fixup has occurred yet, but none of the
- * code we're about to call uses any global variable.
+ * and folded into the former here. No GOT fixup has occurred
+ * yet, but none of the code we're about to call uses any
+ * global variable.
*/
- add sp, sp, #0x10000
+
+ /* Get the initial DTB size */
+ ldr r5, [r6, #4]
+#ifndef __ARMEB__
+ /* convert to little endian */
+ eor r1, r5, r5, ror #16
+ bic r1, r1, #0x00ff0000
+ mov r5, r5, ror #8
+ eor r5, r5, r1, lsr #8
+#endif
+ /* 50% DTB growth should be good enough */
+ add r5, r5, r5, lsr #1
+ /* preserve 64-bit alignment */
+ add r5, r5, #7
+ bic r5, r5, #7
+ /* clamp to 32KB min and 1MB max */
+ cmp r5, #(1 << 15)
+ movlo r5, #(1 << 15)
+ cmp r5, #(1 << 20)
+ movhi r5, #(1 << 20)
+ /* temporarily relocate the stack past the DTB work space */
+ add sp, sp, r5
+
stmfd sp!, {r0-r3, ip, lr}
mov r0, r8
mov r1, r6
- sub r2, sp, r6
+ mov r2, r5
bl atags_to_fdt
/*
@@ -285,11 +306,11 @@ restart: adr r0, LC0
bic r0, r0, #1
add r0, r0, #0x100
mov r1, r6
- sub r2, sp, r6
+ mov r2, r5
bleq atags_to_fdt
ldmfd sp!, {r0-r3, ip, lr}
- sub sp, sp, #0x10000
+ sub sp, sp, r5
#endif
mov r8, r6 @ use the appended device tree
@@ -306,7 +327,7 @@ restart: adr r0, LC0
subs r1, r5, r1
addhi r9, r9, r1
- /* Get the dtb's size */
+ /* Get the current DTB size */
ldr r5, [r6, #4]
#ifndef __ARMEB__
/* convert r5 (dtb size) to little endian */
diff --git a/arch/arm/boot/dts/Makefile b/arch/arm/boot/dts/Makefile
index a8873b8d9ed1..a1c776b8dcec 100644
--- a/arch/arm/boot/dts/Makefile
+++ b/arch/arm/boot/dts/Makefile
@@ -470,7 +470,6 @@ dtb-$(CONFIG_ARCH_SHMOBILE_LEGACY) += \
r8a7778-bockw.dtb \
r8a7778-bockw-reference.dtb \
r8a7779-marzen.dtb \
- r8a7790-lager.dtb \
sh7372-mackerel.dtb \
sh73a0-kzm9g.dtb \
sh73a0-kzm9g-reference.dtb
diff --git a/arch/arm/boot/dts/am335x-evm.dts b/arch/arm/boot/dts/am335x-evm.dts
index 54f118c08db8..66342515df20 100644
--- a/arch/arm/boot/dts/am335x-evm.dts
+++ b/arch/arm/boot/dts/am335x-evm.dts
@@ -648,6 +648,7 @@
ti,x-plate-resistance = <200>;
ti,coordinate-readouts = <5>;
ti,wire-config = <0x00 0x11 0x22 0x33>;
+ ti,charge-delay = <0x400>;
};
adc {
diff --git a/arch/arm/boot/dts/am3517.dtsi b/arch/arm/boot/dts/am3517.dtsi
index 5a452fdd7c5d..c90724bded10 100644
--- a/arch/arm/boot/dts/am3517.dtsi
+++ b/arch/arm/boot/dts/am3517.dtsi
@@ -31,6 +31,7 @@
status = "disabled";
reg = <0x5c000000 0x30000>;
interrupts = <67 68 69 70>;
+ syscon = <&omap3_scm_general>;
ti,davinci-ctrl-reg-offset = <0x10000>;
ti,davinci-ctrl-mod-reg-offset = <0>;
ti,davinci-ctrl-ram-offset = <0x20000>;
diff --git a/arch/arm/boot/dts/armada-370-netgear-rn102.dts b/arch/arm/boot/dts/armada-370-netgear-rn102.dts
index 7c5c4ff941ec..3f8cc3845a5e 100644
--- a/arch/arm/boot/dts/armada-370-netgear-rn102.dts
+++ b/arch/arm/boot/dts/armada-370-netgear-rn102.dts
@@ -120,6 +120,7 @@
isl12057: isl12057@68 {
compatible = "isil,isl12057";
reg = <0x68>;
+ isil,irq2-can-wakeup-machine;
};
g762: g762@3e {
diff --git a/arch/arm/boot/dts/armada-370-netgear-rn104.dts b/arch/arm/boot/dts/armada-370-netgear-rn104.dts
index 1de53b59283a..99eb8a014ac6 100644
--- a/arch/arm/boot/dts/armada-370-netgear-rn104.dts
+++ b/arch/arm/boot/dts/armada-370-netgear-rn104.dts
@@ -126,6 +126,7 @@
isl12057: isl12057@68 {
compatible = "isil,isl12057";
reg = <0x68>;
+ isil,irq2-can-wakeup-machine;
};
g762: g762@3e {
diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi
index 54ebce71f802..1dff30a81e24 100644
--- a/arch/arm/boot/dts/armada-38x.dtsi
+++ b/arch/arm/boot/dts/armada-38x.dtsi
@@ -499,6 +499,13 @@
clocks = <&gateclk 4>;
};
+ rtc@a3800 {
+ compatible = "marvell,armada-380-rtc";
+ reg = <0xa3800 0x20>, <0x184a0 0x0c>;
+ reg-names = "rtc", "rtc-soc";
+ interrupts = <GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
sata@a8000 {
compatible = "marvell,armada-380-ahci";
reg = <0xa8000 0x2000>;
diff --git a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
index a7ceafd5808d..99cb9a8401b4 100644
--- a/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
+++ b/arch/arm/boot/dts/armada-xp-netgear-rn2120.dts
@@ -133,6 +133,7 @@
isl12057: isl12057@68 {
compatible = "isil,isl12057";
reg = <0x68>;
+ isil,irq2-can-wakeup-machine;
};
/* Controller for rear fan #1 of 3 (Protechnic
diff --git a/arch/arm/boot/dts/at91sam9263.dtsi b/arch/arm/boot/dts/at91sam9263.dtsi
index d7e8a2420ad3..1f67bb4c144e 100644
--- a/arch/arm/boot/dts/at91sam9263.dtsi
+++ b/arch/arm/boot/dts/at91sam9263.dtsi
@@ -984,6 +984,8 @@
interrupts = <26 IRQ_TYPE_LEVEL_HIGH 3>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_fb>;
+ clocks = <&lcd_clk>, <&lcd_clk>;
+ clock-names = "lcdc_clk", "hclk";
status = "disabled";
};
diff --git a/arch/arm/boot/dts/berlin2q-marvell-dmp.dts b/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
index 28e7e2060c33..a98ac1bd8f65 100644
--- a/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
+++ b/arch/arm/boot/dts/berlin2q-marvell-dmp.dts
@@ -65,6 +65,8 @@
};
&sdhci2 {
+ broken-cd;
+ bus-width = <8>;
non-removable;
status = "okay";
};
diff --git a/arch/arm/boot/dts/berlin2q.dtsi b/arch/arm/boot/dts/berlin2q.dtsi
index 41a683fd079c..be5397288d24 100644
--- a/arch/arm/boot/dts/berlin2q.dtsi
+++ b/arch/arm/boot/dts/berlin2q.dtsi
@@ -91,7 +91,8 @@
compatible = "mrvl,pxav3-mmc";
reg = <0xab1000 0x200>;
interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&chip CLKID_SDIO1XIN>;
+ clocks = <&chip CLKID_NFC_ECC>, <&chip CLKID_NFC>;
+ clock-names = "io", "core";
status = "disabled";
};
@@ -356,36 +357,6 @@
interrupt-parent = <&gic>;
interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
};
-
- gpio4: gpio@5000 {
- compatible = "snps,dw-apb-gpio";
- reg = <0x5000 0x400>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- porte: gpio-port@4 {
- compatible = "snps,dw-apb-gpio-port";
- gpio-controller;
- #gpio-cells = <2>;
- snps,nr-gpios = <32>;
- reg = <0>;
- };
- };
-
- gpio5: gpio@c000 {
- compatible = "snps,dw-apb-gpio";
- reg = <0xc000 0x400>;
- #address-cells = <1>;
- #size-cells = <0>;
-
- portf: gpio-port@5 {
- compatible = "snps,dw-apb-gpio-port";
- gpio-controller;
- #gpio-cells = <2>;
- snps,nr-gpios = <32>;
- reg = <0>;
- };
- };
};
chip: chip-control@ea0000 {
@@ -474,6 +445,21 @@
ranges = <0 0xfc0000 0x10000>;
interrupt-parent = <&sic>;
+ sm_gpio1: gpio@5000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0x5000 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ portf: gpio-port@5 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <32>;
+ reg = <0>;
+ };
+ };
+
i2c2: i2c@7000 {
compatible = "snps,designware-i2c";
#address-cells = <1>;
@@ -524,6 +510,21 @@
status = "disabled";
};
+ sm_gpio0: gpio@c000 {
+ compatible = "snps,dw-apb-gpio";
+ reg = <0xc000 0x400>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ porte: gpio-port@4 {
+ compatible = "snps,dw-apb-gpio-port";
+ gpio-controller;
+ #gpio-cells = <2>;
+ snps,nr-gpios = <32>;
+ reg = <0>;
+ };
+ };
+
sysctrl: pin-controller@d000 {
compatible = "marvell,berlin2q-system-ctrl";
reg = <0xd000 0x100>;
diff --git a/arch/arm/boot/dts/dra7-evm.dts b/arch/arm/boot/dts/dra7-evm.dts
index c1d0ac7bd002..746cddb1b8f5 100644
--- a/arch/arm/boot/dts/dra7-evm.dts
+++ b/arch/arm/boot/dts/dra7-evm.dts
@@ -522,23 +522,23 @@
};
partition@5 {
label = "QSPI.u-boot-spl-os";
- reg = <0x00140000 0x00010000>;
+ reg = <0x00140000 0x00080000>;
};
partition@6 {
label = "QSPI.u-boot-env";
- reg = <0x00150000 0x00010000>;
+ reg = <0x001c0000 0x00010000>;
};
partition@7 {
label = "QSPI.u-boot-env.backup1";
- reg = <0x00160000 0x0010000>;
+ reg = <0x001d0000 0x0010000>;
};
partition@8 {
label = "QSPI.kernel";
- reg = <0x00170000 0x0800000>;
+ reg = <0x001e0000 0x0800000>;
};
partition@9 {
label = "QSPI.file-system";
- reg = <0x00970000 0x01690000>;
+ reg = <0x009e0000 0x01620000>;
};
};
};
diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index fffe768477da..5827fedafd43 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -1255,6 +1255,8 @@
tx-fifo-resize;
maximum-speed = "super-speed";
dr_mode = "otg";
+ snps,dis_u3_susphy_quirk;
+ snps,dis_u2_susphy_quirk;
};
};
@@ -1276,6 +1278,8 @@
tx-fifo-resize;
maximum-speed = "high-speed";
dr_mode = "otg";
+ snps,dis_u3_susphy_quirk;
+ snps,dis_u2_susphy_quirk;
};
};
@@ -1297,6 +1301,8 @@
tx-fifo-resize;
maximum-speed = "high-speed";
dr_mode = "otg";
+ snps,dis_u3_susphy_quirk;
+ snps,dis_u2_susphy_quirk;
};
};
diff --git a/arch/arm/boot/dts/exynos4.dtsi b/arch/arm/boot/dts/exynos4.dtsi
index d1759bf5202f..76173cacd450 100644
--- a/arch/arm/boot/dts/exynos4.dtsi
+++ b/arch/arm/boot/dts/exynos4.dtsi
@@ -61,9 +61,12 @@
reg = <0x03830000 0x100>;
clocks = <&clock_audss EXYNOS_I2S_BUS>;
clock-names = "iis";
+ #clock-cells = <1>;
+ clock-output-names = "i2s_cdclk0";
dmas = <&pdma0 12>, <&pdma0 11>, <&pdma0 10>;
dma-names = "tx", "rx", "tx-sec";
samsung,idma-addr = <0x03000000>;
+ #sound-dai-cells = <1>;
status = "disabled";
};
@@ -376,22 +379,28 @@
};
i2s1: i2s@13960000 {
- compatible = "samsung,s5pv210-i2s";
+ compatible = "samsung,s3c6410-i2s";
reg = <0x13960000 0x100>;
clocks = <&clock CLK_I2S1>;
clock-names = "iis";
+ #clock-cells = <1>;
+ clock-output-names = "i2s_cdclk1";
dmas = <&pdma1 12>, <&pdma1 11>;
dma-names = "tx", "rx";
+ #sound-dai-cells = <1>;
status = "disabled";
};
i2s2: i2s@13970000 {
- compatible = "samsung,s5pv210-i2s";
+ compatible = "samsung,s3c6410-i2s";
reg = <0x13970000 0x100>;
clocks = <&clock CLK_I2S2>;
clock-names = "iis";
+ #clock-cells = <1>;
+ clock-output-names = "i2s_cdclk2";
dmas = <&pdma0 14>, <&pdma0 13>;
dma-names = "tx", "rx";
+ #sound-dai-cells = <1>;
status = "disabled";
};
diff --git a/arch/arm/boot/dts/exynos4210-origen.dts b/arch/arm/boot/dts/exynos4210-origen.dts
index f767c425d0b5..b81146141402 100644
--- a/arch/arm/boot/dts/exynos4210-origen.dts
+++ b/arch/arm/boot/dts/exynos4210-origen.dts
@@ -31,6 +31,7 @@
chosen {
bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC2,115200 init=/linuxrc";
+ stdout-path = &serial_2;
};
regulators {
diff --git a/arch/arm/boot/dts/exynos4210-smdkv310.dts b/arch/arm/boot/dts/exynos4210-smdkv310.dts
index 676e6e0c8cf3..86216fff1b4f 100644
--- a/arch/arm/boot/dts/exynos4210-smdkv310.dts
+++ b/arch/arm/boot/dts/exynos4210-smdkv310.dts
@@ -27,6 +27,7 @@
chosen {
bootargs = "root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc";
+ stdout-path = &serial_1;
};
sdhci@12530000 {
diff --git a/arch/arm/boot/dts/exynos4210-trats.dts b/arch/arm/boot/dts/exynos4210-trats.dts
index 1c0c7be02616..3d6652a4b6cb 100644
--- a/arch/arm/boot/dts/exynos4210-trats.dts
+++ b/arch/arm/boot/dts/exynos4210-trats.dts
@@ -28,6 +28,7 @@
chosen {
bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5";
+ stdout-path = &serial_2;
};
regulators {
diff --git a/arch/arm/boot/dts/exynos4210-universal_c210.dts b/arch/arm/boot/dts/exynos4210-universal_c210.dts
index 08f89e0ff2b8..b57e6b82ea20 100644
--- a/arch/arm/boot/dts/exynos4210-universal_c210.dts
+++ b/arch/arm/boot/dts/exynos4210-universal_c210.dts
@@ -26,6 +26,7 @@
chosen {
bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rw rootwait earlyprintk panic=5 maxcpus=1";
+ stdout-path = &serial_2;
};
sysram@02020000 {
diff --git a/arch/arm/boot/dts/exynos4210.dtsi b/arch/arm/boot/dts/exynos4210.dtsi
index 7c15880bc8ba..67c832c9dcf1 100644
--- a/arch/arm/boot/dts/exynos4210.dtsi
+++ b/arch/arm/boot/dts/exynos4210.dtsi
@@ -82,6 +82,15 @@
#power-domain-cells = <0>;
};
+ l2c: l2-cache-controller@10502000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x10502000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ arm,tag-latency = <2 2 1>;
+ arm,data-latency = <2 2 1>;
+ };
+
gic: interrupt-controller@10490000 {
cpu-offset = <0x8000>;
};
diff --git a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
index ffcf17bbf63b..de80b5bba204 100644
--- a/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
+++ b/arch/arm/boot/dts/exynos4412-odroid-common.dtsi
@@ -7,10 +7,15 @@
* published by the Free Software Foundation.
*/
+#include <dt-bindings/sound/samsung-i2s.h>
#include <dt-bindings/input/input.h>
#include "exynos4412.dtsi"
/ {
+ chosen {
+ stdout-path = &serial_1;
+ };
+
firmware@0204F000 {
compatible = "samsung,secure-firmware";
reg = <0x0204F000 0x1000>;
@@ -37,14 +42,13 @@
pinctrl-names = "default";
status = "okay";
clocks = <&clock_audss EXYNOS_I2S_BUS>,
- <&clock_audss EXYNOS_DOUT_AUD_BUS>;
- clock-names = "iis", "i2s_opclk0";
+ <&clock_audss EXYNOS_DOUT_AUD_BUS>,
+ <&clock_audss EXYNOS_SCLK_I2S>;
+ clock-names = "iis", "i2s_opclk0", "i2s_opclk1";
};
sound: sound {
- compatible = "samsung,odroidx2-audio";
- samsung,i2s-controller = <&i2s0>;
- samsung,audio-codec = <&max98090>;
+ compatible = "simple-audio-card";
assigned-clocks = <&clock_audss EXYNOS_MOUT_AUDSS>,
<&clock_audss EXYNOS_MOUT_I2S>,
<&clock_audss EXYNOS_DOUT_SRP>,
@@ -55,6 +59,20 @@
<0>,
<192000000>,
<19200000>;
+
+ simple-audio-card,format = "i2s";
+ simple-audio-card,bitclock-master = <&link0_codec>;
+ simple-audio-card,frame-master = <&link0_codec>;
+
+ simple-audio-card,cpu {
+ sound-dai = <&i2s0 0>;
+ system-clock-frequency = <19200000>;
+ };
+
+ link0_codec: simple-audio-card,codec {
+ sound-dai = <&max98090>;
+ clocks = <&i2s0 CLK_I2S_CDCLK>;
+ };
};
mmc@12550000 {
@@ -373,6 +391,9 @@
reg = <0x10>;
interrupt-parent = <&gpx0>;
interrupts = <0 0>;
+ clocks = <&i2s0 CLK_I2S_CDCLK>;
+ clock-names = "mclk";
+ #sound-dai-cells = <0>;
};
};
diff --git a/arch/arm/boot/dts/exynos4412-odroidu3.dts b/arch/arm/boot/dts/exynos4412-odroidu3.dts
index c8a64be55d07..44684e57ead1 100644
--- a/arch/arm/boot/dts/exynos4412-odroidu3.dts
+++ b/arch/arm/boot/dts/exynos4412-odroidu3.dts
@@ -49,9 +49,11 @@
};
&sound {
- compatible = "samsung,odroidu3-audio";
- samsung,model = "Odroid-U3";
- samsung,audio-routing =
+ simple-audio-card,name = "Odroid-U3";
+ simple-audio-card,widgets =
+ "Headphone", "Headphone Jack",
+ "Speakers", "Speakers";
+ simple-audio-card,routing =
"Headphone Jack", "HPL",
"Headphone Jack", "HPR",
"Headphone Jack", "MICBIAS",
diff --git a/arch/arm/boot/dts/exynos4412-odroidx2.dts b/arch/arm/boot/dts/exynos4412-odroidx2.dts
index 96b43f4497cc..6e33678562ae 100644
--- a/arch/arm/boot/dts/exynos4412-odroidx2.dts
+++ b/arch/arm/boot/dts/exynos4412-odroidx2.dts
@@ -23,8 +23,12 @@
};
&sound {
- samsung,model = "Odroid-X2";
- samsung,audio-routing =
+ simple-audio-card,name = "Odroid-X2";
+ simple-audio-card,widgets =
+ "Headphone", "Headphone Jack",
+ "Microphone", "Mic Jack",
+ "Microphone", "DMIC";
+ simple-audio-card,routing =
"Headphone Jack", "HPL",
"Headphone Jack", "HPR",
"IN1", "Mic Jack",
diff --git a/arch/arm/boot/dts/exynos4412-origen.dts b/arch/arm/boot/dts/exynos4412-origen.dts
index de15114fd07c..bd8b73077d41 100644
--- a/arch/arm/boot/dts/exynos4412-origen.dts
+++ b/arch/arm/boot/dts/exynos4412-origen.dts
@@ -26,6 +26,7 @@
chosen {
bootargs ="console=ttySAC2,115200";
+ stdout-path = &serial_2;
};
firmware@0203F000 {
diff --git a/arch/arm/boot/dts/exynos4412-smdk4412.dts b/arch/arm/boot/dts/exynos4412-smdk4412.dts
index ded0b70f7644..b9256afbcc68 100644
--- a/arch/arm/boot/dts/exynos4412-smdk4412.dts
+++ b/arch/arm/boot/dts/exynos4412-smdk4412.dts
@@ -25,6 +25,7 @@
chosen {
bootargs ="root=/dev/ram0 rw ramdisk=8192 initrd=0x41000000,8M console=ttySAC1,115200 init=/linuxrc";
+ stdout-path = &serial_1;
};
g2d@10800000 {
diff --git a/arch/arm/boot/dts/exynos4412-tiny4412.dts b/arch/arm/boot/dts/exynos4412-tiny4412.dts
index ea6929d9c621..d46fd4c2aeaa 100644
--- a/arch/arm/boot/dts/exynos4412-tiny4412.dts
+++ b/arch/arm/boot/dts/exynos4412-tiny4412.dts
@@ -18,6 +18,10 @@
model = "FriendlyARM TINY4412 board based on Exynos4412";
compatible = "friendlyarm,tiny4412", "samsung,exynos4412", "samsung,exynos4";
+ chosen {
+ stdout-path = &serial_0;
+ };
+
memory {
reg = <0x40000000 0x40000000>;
};
diff --git a/arch/arm/boot/dts/exynos4412-trats2.dts b/arch/arm/boot/dts/exynos4412-trats2.dts
index d3b3f4f4653e..21f748083586 100644
--- a/arch/arm/boot/dts/exynos4412-trats2.dts
+++ b/arch/arm/boot/dts/exynos4412-trats2.dts
@@ -34,6 +34,7 @@
chosen {
bootargs = "console=ttySAC2,115200N8 root=/dev/mmcblk0p5 rootwait earlyprintk panic=5";
+ stdout-path = &serial_2;
};
firmware@0204F000 {
diff --git a/arch/arm/boot/dts/exynos4x12.dtsi b/arch/arm/boot/dts/exynos4x12.dtsi
index af59cab53bd9..f5e0ae780d6c 100644
--- a/arch/arm/boot/dts/exynos4x12.dtsi
+++ b/arch/arm/boot/dts/exynos4x12.dtsi
@@ -55,6 +55,20 @@
#power-domain-cells = <0>;
};
+ l2c: l2-cache-controller@10502000 {
+ compatible = "arm,pl310-cache";
+ reg = <0x10502000 0x1000>;
+ cache-unified;
+ cache-level = <2>;
+ arm,tag-latency = <2 2 1>;
+ arm,data-latency = <3 2 1>;
+ arm,double-linefill = <1>;
+ arm,double-linefill-incr = <0>;
+ arm,double-linefill-wrap = <1>;
+ arm,prefetch-drop = <1>;
+ arm,prefetch-offset = <7>;
+ };
+
clock: clock-controller@10030000 {
compatible = "samsung,exynos4412-clock";
reg = <0x10030000 0x20000>;
diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi
index 2b5a62c91d26..9bb1b0b738f5 100644
--- a/arch/arm/boot/dts/exynos5250.dtsi
+++ b/arch/arm/boot/dts/exynos5250.dtsi
@@ -738,7 +738,7 @@
dp_phy: video-phy@10040720 {
compatible = "samsung,exynos5250-dp-video-phy";
- reg = <0x10040720 4>;
+ samsung,pmu-syscon = <&pmu_system_controller>;
#phy-cells = <0>;
};
diff --git a/arch/arm/boot/dts/exynos5420-arndale-octa.dts b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
index aa7a7d727a7e..db2c1c4cd900 100644
--- a/arch/arm/boot/dts/exynos5420-arndale-octa.dts
+++ b/arch/arm/boot/dts/exynos5420-arndale-octa.dts
@@ -372,3 +372,7 @@
&usbdrd_dwc3_1 {
dr_mode = "host";
};
+
+&cci {
+ status = "disabled";
+};
diff --git a/arch/arm/boot/dts/exynos5420.dtsi b/arch/arm/boot/dts/exynos5420.dtsi
index a0a3b2829208..9dc2e9773b30 100644
--- a/arch/arm/boot/dts/exynos5420.dtsi
+++ b/arch/arm/boot/dts/exynos5420.dtsi
@@ -120,7 +120,7 @@
};
};
- cci@10d20000 {
+ cci: cci@10d20000 {
compatible = "arm,cci-400";
#address-cells = <1>;
#size-cells = <1>;
@@ -521,8 +521,8 @@
};
dp_phy: video-phy@10040728 {
- compatible = "samsung,exynos5250-dp-video-phy";
- reg = <0x10040728 4>;
+ compatible = "samsung,exynos5420-dp-video-phy";
+ samsung,pmu-syscon = <&pmu_system_controller>;
#phy-cells = <0>;
};
diff --git a/arch/arm/boot/dts/imx25.dtsi b/arch/arm/boot/dts/imx25.dtsi
index 58d3c3cf2923..e4d3aecc4ed2 100644
--- a/arch/arm/boot/dts/imx25.dtsi
+++ b/arch/arm/boot/dts/imx25.dtsi
@@ -162,7 +162,7 @@
#size-cells = <0>;
compatible = "fsl,imx25-cspi", "fsl,imx35-cspi";
reg = <0x43fa4000 0x4000>;
- clocks = <&clks 62>, <&clks 62>;
+ clocks = <&clks 78>, <&clks 78>;
clock-names = "ipg", "per";
interrupts = <14>;
status = "disabled";
@@ -369,7 +369,7 @@
compatible = "fsl,imx25-pwm", "fsl,imx27-pwm";
#pwm-cells = <2>;
reg = <0x53fa0000 0x4000>;
- clocks = <&clks 106>, <&clks 36>;
+ clocks = <&clks 106>, <&clks 52>;
clock-names = "ipg", "per";
interrupts = <36>;
};
@@ -388,7 +388,7 @@
compatible = "fsl,imx25-pwm", "fsl,imx27-pwm";
#pwm-cells = <2>;
reg = <0x53fa8000 0x4000>;
- clocks = <&clks 107>, <&clks 36>;
+ clocks = <&clks 107>, <&clks 52>;
clock-names = "ipg", "per";
interrupts = <41>;
};
@@ -429,7 +429,7 @@
pwm4: pwm@53fc8000 {
compatible = "fsl,imx25-pwm", "fsl,imx27-pwm";
reg = <0x53fc8000 0x4000>;
- clocks = <&clks 108>, <&clks 36>;
+ clocks = <&clks 108>, <&clks 52>;
clock-names = "ipg", "per";
interrupts = <42>;
};
@@ -476,7 +476,7 @@
compatible = "fsl,imx25-pwm", "fsl,imx27-pwm";
#pwm-cells = <2>;
reg = <0x53fe0000 0x4000>;
- clocks = <&clks 105>, <&clks 36>;
+ clocks = <&clks 105>, <&clks 52>;
clock-names = "ipg", "per";
interrupts = <26>;
};
diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts
index 56569cecaa78..649befeb2cf9 100644
--- a/arch/arm/boot/dts/imx51-babbage.dts
+++ b/arch/arm/boot/dts/imx51-babbage.dts
@@ -127,24 +127,12 @@
#address-cells = <1>;
#size-cells = <0>;
- reg_usbh1_vbus: regulator@0 {
- compatible = "regulator-fixed";
- pinctrl-names = "default";
- pinctrl-0 = <&pinctrl_usbh1reg>;
- reg = <0>;
- regulator-name = "usbh1_vbus";
- regulator-min-microvolt = <5000000>;
- regulator-max-microvolt = <5000000>;
- gpio = <&gpio2 5 GPIO_ACTIVE_HIGH>;
- enable-active-high;
- };
-
- reg_usbotg_vbus: regulator@1 {
+ reg_hub_reset: regulator@0 {
compatible = "regulator-fixed";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usbotgreg>;
- reg = <1>;
- regulator-name = "usbotg_vbus";
+ reg = <0>;
+ regulator-name = "hub_reset";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>;
@@ -176,6 +164,7 @@
reg = <0>;
clocks = <&clks IMX5_CLK_DUMMY>;
clock-names = "main_clk";
+ reset-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>;
};
};
};
@@ -419,7 +408,7 @@
&usbh1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usbh1>;
- vbus-supply = <&reg_usbh1_vbus>;
+ vbus-supply = <&reg_hub_reset>;
fsl,usbphy = <&usbh1phy>;
phy_type = "ulpi";
status = "okay";
@@ -429,7 +418,6 @@
dr_mode = "otg";
disable-over-current;
phy_type = "utmi_wide";
- vbus-supply = <&reg_usbotg_vbus>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/imx6qdl.dtsi b/arch/arm/boot/dts/imx6qdl.dtsi
index f6c6a6e1cf3d..d6c69ec44314 100644
--- a/arch/arm/boot/dts/imx6qdl.dtsi
+++ b/arch/arm/boot/dts/imx6qdl.dtsi
@@ -335,8 +335,8 @@
vpu: vpu@02040000 {
compatible = "cnm,coda960";
reg = <0x02040000 0x3c000>;
- interrupts = <0 3 IRQ_TYPE_LEVEL_HIGH>,
- <0 12 IRQ_TYPE_LEVEL_HIGH>;
+ interrupts = <0 12 IRQ_TYPE_LEVEL_HIGH>,
+ <0 3 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "bit", "jpeg";
clocks = <&clks IMX6QDL_CLK_VPU_AXI>,
<&clks IMX6QDL_CLK_MMDC_CH0_AXI>;
diff --git a/arch/arm/boot/dts/imx6sx-sdb.dts b/arch/arm/boot/dts/imx6sx-sdb.dts
index cdffe8465c46..32f07d6b4042 100644
--- a/arch/arm/boot/dts/imx6sx-sdb.dts
+++ b/arch/arm/boot/dts/imx6sx-sdb.dts
@@ -159,13 +159,28 @@
pinctrl-0 = <&pinctrl_enet1>;
phy-supply = <&reg_enet_3v3>;
phy-mode = "rgmii";
+ phy-handle = <&ethphy1>;
status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+
+ ethphy2: ethernet-phy@2 {
+ reg = <2>;
+ };
+ };
};
&fec2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet2>;
phy-mode = "rgmii";
+ phy-handle = <&ethphy2>;
status = "okay";
};
diff --git a/arch/arm/boot/dts/ls1021a.dtsi b/arch/arm/boot/dts/ls1021a.dtsi
index 657da14cb4b5..c70bb27ac65a 100644
--- a/arch/arm/boot/dts/ls1021a.dtsi
+++ b/arch/arm/boot/dts/ls1021a.dtsi
@@ -142,6 +142,7 @@
scfg: scfg@1570000 {
compatible = "fsl,ls1021a-scfg", "syscon";
reg = <0x0 0x1570000 0x0 0x10000>;
+ big-endian;
};
clockgen: clocking@1ee1000 {
diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts
index abf1daf84926..60403273f83e 100644
--- a/arch/arm/boot/dts/omap3-n900.dts
+++ b/arch/arm/boot/dts/omap3-n900.dts
@@ -699,11 +699,9 @@
};
};
+ /* Ethernet is on some early development boards and qemu */
ethernet@gpmc {
compatible = "smsc,lan91c94";
-
- status = "disabled";
-
interrupt-parent = <&gpio2>;
interrupts = <22 IRQ_TYPE_LEVEL_HIGH>; /* gpio54 */
reg = <1 0x300 0xf>; /* 16 byte IO range at offset 0x300 */
diff --git a/arch/arm/boot/dts/r8a7790-lager.dts b/arch/arm/boot/dts/r8a7790-lager.dts
index 2a191b56c9f9..0c3b6783b72a 100644
--- a/arch/arm/boot/dts/r8a7790-lager.dts
+++ b/arch/arm/boot/dts/r8a7790-lager.dts
@@ -47,12 +47,12 @@
compatible = "renesas,lager", "renesas,r8a7790";
aliases {
- serial6 = &scifa0;
- serial7 = &scifa1;
+ serial0 = &scifa0;
+ serial1 = &scifa1;
};
chosen {
- bootargs = "console=ttySC6,115200 ignore_loglevel rw root=/dev/nfs ip=dhcp";
+ bootargs = "ignore_loglevel rw root=/dev/nfs ip=dhcp";
stdout-path = &scifa0;
};
diff --git a/arch/arm/boot/dts/r8a7791-koelsch.dts b/arch/arm/boot/dts/r8a7791-koelsch.dts
index 96f5b5877f22..a3c27807f6c5 100644
--- a/arch/arm/boot/dts/r8a7791-koelsch.dts
+++ b/arch/arm/boot/dts/r8a7791-koelsch.dts
@@ -48,8 +48,8 @@
compatible = "renesas,koelsch", "renesas,r8a7791";
aliases {
- serial6 = &scif0;
- serial7 = &scif1;
+ serial0 = &scif0;
+ serial1 = &scif1;
};
chosen {
diff --git a/arch/arm/boot/dts/rk3288-evb-rk808.dts b/arch/arm/boot/dts/rk3288-evb-rk808.dts
index 3f7aa9e2e76a..a1c294bf7fed 100644
--- a/arch/arm/boot/dts/rk3288-evb-rk808.dts
+++ b/arch/arm/boot/dts/rk3288-evb-rk808.dts
@@ -15,6 +15,13 @@
/ {
compatible = "rockchip,rk3288-evb-rk808", "rockchip,rk3288";
+
+ ext_gmac: external-gmac-clock {
+ compatible = "fixed-clock";
+ clock-frequency = <125000000>;
+ clock-output-names = "ext_gmac";
+ #clock-cells = <0>;
+ };
};
&cpu0 {
@@ -202,3 +209,19 @@
};
};
};
+
+&gmac {
+ phy-supply = <&vcc_phy>;
+ phy-mode = "rgmii";
+ clock_in_out = "input";
+ snps,reset-gpio = <&gpio4 7 0>;
+ snps,reset-active-low;
+ snps,reset-delays-us = <0 10000 1000000>;
+ assigned-clocks = <&cru SCLK_MAC>;
+ assigned-clock-parents = <&ext_gmac>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&rgmii_pins>;
+ tx_delay = <0x30>;
+ rx_delay = <0x10>;
+ status = "ok";
+};
diff --git a/arch/arm/boot/dts/rk3288-evb.dtsi b/arch/arm/boot/dts/rk3288-evb.dtsi
index 86ede5893ab6..5e895a514a0b 100644
--- a/arch/arm/boot/dts/rk3288-evb.dtsi
+++ b/arch/arm/boot/dts/rk3288-evb.dtsi
@@ -90,6 +90,19 @@
regulator-always-on;
regulator-boot-on;
};
+
+ vcc_phy: vcc-phy-regulator {
+ compatible = "regulator-fixed";
+ enable-active-high;
+ gpio = <&gpio0 6 GPIO_ACTIVE_HIGH>;
+ pinctrl-names = "default";
+ pinctrl-0 = <&eth_phy_pwr>;
+ regulator-name = "vcc_phy";
+ regulator-min-microvolt = <3300000>;
+ regulator-max-microvolt = <3300000>;
+ regulator-always-on;
+ regulator-boot-on;
+ };
};
&emmc {
@@ -164,6 +177,15 @@
};
&pinctrl {
+ pcfg_pull_none_drv_8ma: pcfg-pull-none-drv-8ma {
+ drive-strength = <8>;
+ };
+
+ pcfg_pull_up_drv_8ma: pcfg-pull-up-drv-8ma {
+ bias-pull-up;
+ drive-strength = <8>;
+ };
+
backlight {
bl_en: bl-en {
rockchip,pins = <7 2 RK_FUNC_GPIO &pcfg_pull_none>;
@@ -182,11 +204,38 @@
};
};
+ sdmmc {
+ /*
+ * Default drive strength isn't enough to achieve even
+ * high-speed mode on EVB board so bump up to 8ma.
+ */
+ sdmmc_bus4: sdmmc-bus4 {
+ rockchip,pins = <6 16 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
+ <6 17 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
+ <6 18 RK_FUNC_1 &pcfg_pull_up_drv_8ma>,
+ <6 19 RK_FUNC_1 &pcfg_pull_up_drv_8ma>;
+ };
+
+ sdmmc_clk: sdmmc-clk {
+ rockchip,pins = <6 20 RK_FUNC_1 &pcfg_pull_none_drv_8ma>;
+ };
+
+ sdmmc_cmd: sdmmc-cmd {
+ rockchip,pins = <6 21 RK_FUNC_1 &pcfg_pull_up_drv_8ma>;
+ };
+ };
+
usb {
host_vbus_drv: host-vbus-drv {
rockchip,pins = <0 14 RK_FUNC_GPIO &pcfg_pull_none>;
};
};
+
+ eth_phy {
+ eth_phy_pwr: eth-phy-pwr {
+ rockchip,pins = <0 6 RK_FUNC_GPIO &pcfg_pull_none>;
+ };
+ };
};
&usb_host0_ehci {
diff --git a/arch/arm/boot/dts/rk3288.dtsi b/arch/arm/boot/dts/rk3288.dtsi
index 1141850d0acb..d771f687a13b 100644
--- a/arch/arm/boot/dts/rk3288.dtsi
+++ b/arch/arm/boot/dts/rk3288.dtsi
@@ -397,6 +397,22 @@
status = "disabled";
};
+ gmac: ethernet@ff290000 {
+ compatible = "rockchip,rk3288-gmac";
+ reg = <0xff290000 0x10000>;
+ interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "macirq";
+ rockchip,grf = <&grf>;
+ clocks = <&cru SCLK_MAC>,
+ <&cru SCLK_MAC_RX>, <&cru SCLK_MAC_TX>,
+ <&cru SCLK_MACREF>, <&cru SCLK_MACREF_OUT>,
+ <&cru ACLK_GMAC>, <&cru PCLK_GMAC>;
+ clock-names = "stmmaceth",
+ "mac_clk_rx", "mac_clk_tx",
+ "clk_mac_ref", "clk_mac_refout",
+ "aclk_mac", "pclk_mac";
+ };
+
usb_host0_ehci: usb@ff500000 {
compatible = "generic-ehci";
reg = <0xff500000 0x100>;
@@ -818,6 +834,11 @@
bias-disable;
};
+ pcfg_pull_none_12ma: pcfg-pull-none-12ma {
+ bias-disable;
+ drive-strength = <12>;
+ };
+
sleep {
global_pwroff: global-pwroff {
rockchip,pins = <0 0 RK_FUNC_1 &pcfg_pull_none>;
@@ -1179,5 +1200,38 @@
rockchip,pins = <7 23 3 &pcfg_pull_none>;
};
};
+
+ gmac {
+ rgmii_pins: rgmii-pins {
+ rockchip,pins = <3 30 3 &pcfg_pull_none>,
+ <3 31 3 &pcfg_pull_none>,
+ <3 26 3 &pcfg_pull_none>,
+ <3 27 3 &pcfg_pull_none>,
+ <3 28 3 &pcfg_pull_none_12ma>,
+ <3 29 3 &pcfg_pull_none_12ma>,
+ <3 24 3 &pcfg_pull_none_12ma>,
+ <3 25 3 &pcfg_pull_none_12ma>,
+ <4 0 3 &pcfg_pull_none>,
+ <4 5 3 &pcfg_pull_none>,
+ <4 6 3 &pcfg_pull_none>,
+ <4 9 3 &pcfg_pull_none_12ma>,
+ <4 4 3 &pcfg_pull_none_12ma>,
+ <4 1 3 &pcfg_pull_none>,
+ <4 3 3 &pcfg_pull_none>;
+ };
+
+ rmii_pins: rmii-pins {
+ rockchip,pins = <3 30 3 &pcfg_pull_none>,
+ <3 31 3 &pcfg_pull_none>,
+ <3 28 3 &pcfg_pull_none>,
+ <3 29 3 &pcfg_pull_none>,
+ <4 0 3 &pcfg_pull_none>,
+ <4 5 3 &pcfg_pull_none>,
+ <4 4 3 &pcfg_pull_none>,
+ <4 1 3 &pcfg_pull_none>,
+ <4 2 3 &pcfg_pull_none>,
+ <4 3 3 &pcfg_pull_none>;
+ };
+ };
};
};
diff --git a/arch/arm/boot/dts/sama5d3xmb.dtsi b/arch/arm/boot/dts/sama5d3xmb.dtsi
index e6396b68b408..83bee7a3a617 100644
--- a/arch/arm/boot/dts/sama5d3xmb.dtsi
+++ b/arch/arm/boot/dts/sama5d3xmb.dtsi
@@ -208,7 +208,7 @@
"Headphone Jack", "HPOUTR",
"IN2L", "Line In Jack",
"IN2R", "Line In Jack",
- "MICBIAS", "IN1L",
+ "Mic", "MICBIAS",
"IN1L", "Mic";
atmel,ssc-controller = <&ssc0>;
diff --git a/arch/arm/boot/dts/sama5d4.dtsi b/arch/arm/boot/dts/sama5d4.dtsi
index 5d6d0b3f5768..d986b41b9654 100644
--- a/arch/arm/boot/dts/sama5d4.dtsi
+++ b/arch/arm/boot/dts/sama5d4.dtsi
@@ -1019,7 +1019,7 @@
pit: timer@fc068630 {
compatible = "atmel,at91sam9260-pit";
- reg = <0xfc068630 0xf>;
+ reg = <0xfc068630 0x10>;
interrupts = <3 IRQ_TYPE_LEVEL_HIGH 5>;
clocks = <&h32ck>;
};
diff --git a/arch/arm/boot/dts/ste-nomadik-nhk15.dts b/arch/arm/boot/dts/ste-nomadik-nhk15.dts
index a8c00ee7522a..3d0b8755caee 100644
--- a/arch/arm/boot/dts/ste-nomadik-nhk15.dts
+++ b/arch/arm/boot/dts/ste-nomadik-nhk15.dts
@@ -25,11 +25,11 @@
stmpe2401_1 {
stmpe2401_1_nhk_mode: stmpe2401_1_nhk {
nhk_cfg1 {
- ste,pins = "GPIO76_B20"; // IRQ line
+ pins = "GPIO76_B20"; // IRQ line
ste,input = <0>;
};
nhk_cfg2 {
- ste,pins = "GPIO77_B8"; // reset line
+ pins = "GPIO77_B8"; // reset line
ste,output = <1>;
};
};
@@ -37,11 +37,11 @@
stmpe2401_2 {
stmpe2401_2_nhk_mode: stmpe2401_2_nhk {
nhk_cfg1 {
- ste,pins = "GPIO78_A8"; // IRQ line
+ pins = "GPIO78_A8"; // IRQ line
ste,input = <0>;
};
nhk_cfg2 {
- ste,pins = "GPIO79_C9"; // reset line
+ pins = "GPIO79_C9"; // reset line
ste,output = <1>;
};
};
diff --git a/arch/arm/boot/dts/stih415.dtsi b/arch/arm/boot/dts/stih415.dtsi
index 9198c12765ea..19b019b5f30e 100644
--- a/arch/arm/boot/dts/stih415.dtsi
+++ b/arch/arm/boot/dts/stih415.dtsi
@@ -153,8 +153,8 @@
compatible = "st,stih415-dwmac", "snps,dwmac", "snps,dwmac-3.610";
status = "disabled";
- reg = <0xfe810000 0x8000>, <0x148 0x4>;
- reg-names = "stmmaceth", "sti-ethconf";
+ reg = <0xfe810000 0x8000>;
+ reg-names = "stmmaceth";
interrupts = <0 147 0>, <0 148 0>, <0 149 0>;
interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
@@ -165,7 +165,7 @@
snps,mixed-burst;
snps,force_sf_dma_mode;
- st,syscon = <&syscfg_rear>;
+ st,syscon = <&syscfg_rear 0x148>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_mii0>;
@@ -177,8 +177,8 @@
device_type = "network";
compatible = "st,stih415-dwmac", "snps,dwmac", "snps,dwmac-3.610";
status = "disabled";
- reg = <0xfef08000 0x8000>, <0x74 0x4>;
- reg-names = "stmmaceth", "sti-ethconf";
+ reg = <0xfef08000 0x8000>;
+ reg-names = "stmmaceth";
interrupts = <0 150 0>, <0 151 0>, <0 152 0>;
interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
@@ -186,7 +186,7 @@
snps,mixed-burst;
snps,force_sf_dma_mode;
- st,syscon = <&syscfg_sbc>;
+ st,syscon = <&syscfg_sbc 0x74>;
resets = <&softreset STIH415_ETH1_SOFTRESET>;
reset-names = "stmmaceth";
diff --git a/arch/arm/boot/dts/stih416.dtsi b/arch/arm/boot/dts/stih416.dtsi
index fad9073ddeed..ea28ebadab1a 100644
--- a/arch/arm/boot/dts/stih416.dtsi
+++ b/arch/arm/boot/dts/stih416.dtsi
@@ -163,8 +163,8 @@
device_type = "network";
compatible = "st,stih416-dwmac", "snps,dwmac", "snps,dwmac-3.710";
status = "disabled";
- reg = <0xfe810000 0x8000>, <0x8bc 0x4>;
- reg-names = "stmmaceth", "sti-ethconf";
+ reg = <0xfe810000 0x8000>;
+ reg-names = "stmmaceth";
interrupts = <0 133 0>, <0 134 0>, <0 135 0>;
interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
@@ -172,7 +172,7 @@
snps,pbl = <32>;
snps,mixed-burst;
- st,syscon = <&syscfg_rear>;
+ st,syscon = <&syscfg_rear 0x8bc>;
resets = <&softreset STIH416_ETH0_SOFTRESET>;
reset-names = "stmmaceth";
pinctrl-names = "default";
@@ -185,15 +185,15 @@
device_type = "network";
compatible = "st,stih416-dwmac", "snps,dwmac", "snps,dwmac-3.710";
status = "disabled";
- reg = <0xfef08000 0x8000>, <0x7f0 0x4>;
- reg-names = "stmmaceth", "sti-ethconf";
+ reg = <0xfef08000 0x8000>;
+ reg-names = "stmmaceth";
interrupts = <0 136 0>, <0 137 0>, <0 138 0>;
interrupt-names = "macirq", "eth_wake_irq", "eth_lpi";
snps,pbl = <32>;
snps,mixed-burst;
- st,syscon = <&syscfg_sbc>;
+ st,syscon = <&syscfg_sbc 0x7f0>;
resets = <&softreset STIH416_ETH1_SOFTRESET>;
reset-names = "stmmaceth";
@@ -283,21 +283,21 @@
miphy365x_phy: phy@fe382000 {
compatible = "st,miphy365x-phy";
- st,syscfg = <&syscfg_rear>;
+ st,syscfg = <&syscfg_rear 0x824 0x828>;
#address-cells = <1>;
#size-cells = <1>;
ranges;
phy_port0: port@fe382000 {
#phy-cells = <1>;
- reg = <0xfe382000 0x100>, <0xfe394000 0x100>, <0x824 0x4>;
- reg-names = "sata", "pcie", "syscfg";
+ reg = <0xfe382000 0x100>, <0xfe394000 0x100>;
+ reg-names = "sata", "pcie";
};
phy_port1: port@fe38a000 {
#phy-cells = <1>;
- reg = <0xfe38a000 0x100>, <0xfe804000 0x100>, <0x828 0x4>;
- reg-names = "sata", "pcie", "syscfg";
+ reg = <0xfe38a000 0x100>, <0xfe804000 0x100>;
+ reg-names = "sata", "pcie";
};
};
diff --git a/arch/arm/boot/dts/sun4i-a10.dtsi b/arch/arm/boot/dts/sun4i-a10.dtsi
index 2d7483a500ef..8ca3c1a2063d 100644
--- a/arch/arm/boot/dts/sun4i-a10.dtsi
+++ b/arch/arm/boot/dts/sun4i-a10.dtsi
@@ -22,14 +22,6 @@
aliases {
ethernet0 = &emac;
- serial0 = &uart0;
- serial1 = &uart1;
- serial2 = &uart2;
- serial3 = &uart3;
- serial4 = &uart4;
- serial5 = &uart5;
- serial6 = &uart6;
- serial7 = &uart7;
};
chosen {
diff --git a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
index 6b8180507139..2bbc93b935ca 100644
--- a/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun5i-a10s-olinuxino-micro.dts
@@ -59,6 +59,12 @@
model = "Olimex A10s-Olinuxino Micro";
compatible = "olimex,a10s-olinuxino-micro", "allwinner,sun5i-a10s";
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ };
+
soc@01c00000 {
emac: ethernet@01c0b000 {
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/sun5i-a10s.dtsi b/arch/arm/boot/dts/sun5i-a10s.dtsi
index ac919e621754..905f84d141f0 100644
--- a/arch/arm/boot/dts/sun5i-a10s.dtsi
+++ b/arch/arm/boot/dts/sun5i-a10s.dtsi
@@ -21,10 +21,6 @@
aliases {
ethernet0 = &emac;
- serial0 = &uart0;
- serial1 = &uart1;
- serial2 = &uart2;
- serial3 = &uart3;
};
chosen {
diff --git a/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts b/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts
index 82637db1c55a..03aa04555630 100644
--- a/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts
+++ b/arch/arm/boot/dts/sun5i-a13-hsg-h702.dts
@@ -56,6 +56,10 @@
model = "HSG H702";
compatible = "hsg,h702", "allwinner,sun5i-a13";
+ aliases {
+ serial0 = &uart1;
+ };
+
soc@01c00000 {
mmc0: mmc@01c0f000 {
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
index 64d516200dae..03deb84268ce 100644
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino-micro.dts
@@ -57,6 +57,10 @@
model = "Olimex A13-Olinuxino Micro";
compatible = "olimex,a13-olinuxino-micro", "allwinner,sun5i-a13";
+ aliases {
+ serial0 = &uart1;
+ };
+
soc@01c00000 {
mmc0: mmc@01c0f000 {
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
index 76a4bdeacb96..6b24876ed462 100644
--- a/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
+++ b/arch/arm/boot/dts/sun5i-a13-olinuxino.dts
@@ -59,6 +59,10 @@
model = "Olimex A13-Olinuxino";
compatible = "olimex,a13-olinuxino", "allwinner,sun5i-a13";
+ aliases {
+ serial0 = &uart1;
+ };
+
soc@01c00000 {
mmc0: mmc@01c0f000 {
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/sun5i-a13.dtsi b/arch/arm/boot/dts/sun5i-a13.dtsi
index fd85720ec6a2..4910393d1b09 100644
--- a/arch/arm/boot/dts/sun5i-a13.dtsi
+++ b/arch/arm/boot/dts/sun5i-a13.dtsi
@@ -21,11 +21,6 @@
/ {
interrupt-parent = <&intc>;
- aliases {
- serial0 = &uart1;
- serial1 = &uart3;
- };
-
chosen {
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm/boot/dts/sun6i-a31.dtsi b/arch/arm/boot/dts/sun6i-a31.dtsi
index 805f67a2e02f..47e557656993 100644
--- a/arch/arm/boot/dts/sun6i-a31.dtsi
+++ b/arch/arm/boot/dts/sun6i-a31.dtsi
@@ -57,12 +57,6 @@
interrupt-parent = <&gic>;
aliases {
- serial0 = &uart0;
- serial1 = &uart1;
- serial2 = &uart2;
- serial3 = &uart3;
- serial4 = &uart4;
- serial5 = &uart5;
ethernet0 = &gmac;
};
diff --git a/arch/arm/boot/dts/sun7i-a20-bananapi.dts b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
index 4b0cd776c5c5..5dd139e7792e 100644
--- a/arch/arm/boot/dts/sun7i-a20-bananapi.dts
+++ b/arch/arm/boot/dts/sun7i-a20-bananapi.dts
@@ -59,6 +59,12 @@
model = "LeMaker Banana Pi";
compatible = "lemaker,bananapi", "allwinner,sun7i-a20";
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart3;
+ serial2 = &uart7;
+ };
+
soc@01c00000 {
spi0: spi@01c05000 {
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/sun7i-a20-hummingbird.dts b/arch/arm/boot/dts/sun7i-a20-hummingbird.dts
index 4d6a88ec8c0f..86a944ce19f8 100644
--- a/arch/arm/boot/dts/sun7i-a20-hummingbird.dts
+++ b/arch/arm/boot/dts/sun7i-a20-hummingbird.dts
@@ -23,6 +23,14 @@
model = "Merrii A20 Hummingbird";
compatible = "merrii,a20-hummingbird", "allwinner,sun7i-a20";
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart2;
+ serial2 = &uart3;
+ serial3 = &uart4;
+ serial4 = &uart5;
+ };
+
soc@01c00000 {
mmc0: mmc@01c0f000 {
pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
index d0dcf7260971..714e15ac5416 100644
--- a/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
+++ b/arch/arm/boot/dts/sun7i-a20-olinuxino-micro.dts
@@ -25,6 +25,9 @@
compatible = "olimex,a20-olinuxino-micro", "allwinner,sun7i-a20";
aliases {
+ serial0 = &uart0;
+ serial1 = &uart6;
+ serial2 = &uart7;
spi0 = &spi1;
spi1 = &spi2;
};
diff --git a/arch/arm/boot/dts/sun7i-a20.dtsi b/arch/arm/boot/dts/sun7i-a20.dtsi
index 9108feb44e58..786d491542ac 100644
--- a/arch/arm/boot/dts/sun7i-a20.dtsi
+++ b/arch/arm/boot/dts/sun7i-a20.dtsi
@@ -60,14 +60,6 @@
aliases {
ethernet0 = &gmac;
- serial0 = &uart0;
- serial1 = &uart1;
- serial2 = &uart2;
- serial3 = &uart3;
- serial4 = &uart4;
- serial5 = &uart5;
- serial6 = &uart6;
- serial7 = &uart7;
};
chosen {
diff --git a/arch/arm/boot/dts/sun8i-a23.dtsi b/arch/arm/boot/dts/sun8i-a23.dtsi
index d04944334830..dd34527293e4 100644
--- a/arch/arm/boot/dts/sun8i-a23.dtsi
+++ b/arch/arm/boot/dts/sun8i-a23.dtsi
@@ -56,15 +56,6 @@
/ {
interrupt-parent = <&gic>;
- aliases {
- serial0 = &uart0;
- serial1 = &uart1;
- serial2 = &uart2;
- serial3 = &uart3;
- serial4 = &uart4;
- serial5 = &r_uart;
- };
-
chosen {
#address-cells = <1>;
#size-cells = <1>;
diff --git a/arch/arm/boot/dts/sun9i-a80-optimus.dts b/arch/arm/boot/dts/sun9i-a80-optimus.dts
index c4de9cb9a5f6..a3fed2bdf620 100644
--- a/arch/arm/boot/dts/sun9i-a80-optimus.dts
+++ b/arch/arm/boot/dts/sun9i-a80-optimus.dts
@@ -58,6 +58,11 @@
model = "Merrii A80 Optimus Board";
compatible = "merrii,a80-optimus", "allwinner,sun9i-a80";
+ aliases {
+ serial0 = &uart0;
+ serial1 = &uart4;
+ };
+
chosen {
bootargs = "earlyprintk console=ttyS0,115200";
};
diff --git a/arch/arm/boot/dts/sun9i-a80.dtsi b/arch/arm/boot/dts/sun9i-a80.dtsi
index 9e28ffc6dd90..f0f6fb91f8c3 100644
--- a/arch/arm/boot/dts/sun9i-a80.dtsi
+++ b/arch/arm/boot/dts/sun9i-a80.dtsi
@@ -56,16 +56,6 @@
/ {
interrupt-parent = <&gic>;
- aliases {
- serial0 = &uart0;
- serial1 = &uart1;
- serial2 = &uart2;
- serial3 = &uart3;
- serial4 = &uart4;
- serial5 = &uart5;
- serial6 = &r_uart;
- };
-
cpus {
#address-cells = <1>;
#size-cells = <0>;
diff --git a/arch/arm/boot/dts/tegra124-jetson-tk1.dts b/arch/arm/boot/dts/tegra124-jetson-tk1.dts
index 4eb540be368f..dbfaba09703a 100644
--- a/arch/arm/boot/dts/tegra124-jetson-tk1.dts
+++ b/arch/arm/boot/dts/tegra124-jetson-tk1.dts
@@ -1673,6 +1673,13 @@
nvidia,core-pwr-off-time = <61036>;
nvidia,core-power-req-active-high;
nvidia,sys-clock-req-active-high;
+
+ i2c-thermtrip {
+ nvidia,i2c-controller-id = <4>;
+ nvidia,bus-addr = <0x40>;
+ nvidia,reg-addr = <0x36>;
+ nvidia,reg-data = <0x2>;
+ };
};
/* Serial ATA */
diff --git a/arch/arm/boot/dts/tegra20-seaboard.dts b/arch/arm/boot/dts/tegra20-seaboard.dts
index ea282c7c0ca5..e2fed2712249 100644
--- a/arch/arm/boot/dts/tegra20-seaboard.dts
+++ b/arch/arm/boot/dts/tegra20-seaboard.dts
@@ -406,7 +406,7 @@
clock-frequency = <400000>;
magnetometer@c {
- compatible = "ak,ak8975";
+ compatible = "asahi-kasei,ak8975";
reg = <0xc>;
interrupt-parent = <&gpio>;
interrupts = <TEGRA_GPIO(N, 5) IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/versatile-ab.dts b/arch/arm/boot/dts/versatile-ab.dts
index 27d0d9c8adf3..01f40197ea13 100644
--- a/arch/arm/boot/dts/versatile-ab.dts
+++ b/arch/arm/boot/dts/versatile-ab.dts
@@ -252,6 +252,11 @@
#size-cells = <1>;
ranges = <0 0x10000000 0x10000>;
+ sysreg@0 {
+ compatible = "arm,versatile-sysreg", "syscon";
+ reg = <0x00000 0x1000>;
+ };
+
aaci@4000 {
compatible = "arm,primecell";
reg = <0x4000 0x1000>;
diff --git a/arch/arm/boot/dts/versatile-pb.dts b/arch/arm/boot/dts/versatile-pb.dts
index e36c1e82fea7..b83137f66034 100644
--- a/arch/arm/boot/dts/versatile-pb.dts
+++ b/arch/arm/boot/dts/versatile-pb.dts
@@ -29,6 +29,43 @@
clock-names = "apb_pclk";
};
+ pci-controller@10001000 {
+ compatible = "arm,versatile-pci";
+ device_type = "pci";
+ reg = <0x10001000 0x1000
+ 0x41000000 0x10000
+ 0x42000000 0x100000>;
+ bus-range = <0 0xff>;
+ #address-cells = <3>;
+ #size-cells = <2>;
+ #interrupt-cells = <1>;
+
+ ranges = <0x01000000 0 0x00000000 0x43000000 0 0x00010000 /* downstream I/O */
+ 0x02000000 0 0x50000000 0x50000000 0 0x10000000 /* non-prefetchable memory */
+ 0x42000000 0 0x60000000 0x60000000 0 0x10000000>; /* prefetchable memory */
+
+ interrupt-map-mask = <0x1800 0 0 7>;
+ interrupt-map = <0x1800 0 0 1 &sic 28
+ 0x1800 0 0 2 &sic 29
+ 0x1800 0 0 3 &sic 30
+ 0x1800 0 0 4 &sic 27
+
+ 0x1000 0 0 1 &sic 27
+ 0x1000 0 0 2 &sic 28
+ 0x1000 0 0 3 &sic 29
+ 0x1000 0 0 4 &sic 30
+
+ 0x0800 0 0 1 &sic 30
+ 0x0800 0 0 2 &sic 27
+ 0x0800 0 0 3 &sic 28
+ 0x0800 0 0 4 &sic 29
+
+ 0x0000 0 0 1 &sic 29
+ 0x0000 0 0 2 &sic 30
+ 0x0000 0 0 3 &sic 27
+ 0x0000 0 0 4 &sic 28>;
+ };
+
fpga {
uart@9000 {
compatible = "arm,pl011", "arm,primecell";
diff --git a/arch/arm/boot/dts/vf610-twr.dts b/arch/arm/boot/dts/vf610-twr.dts
index 289fef20cd83..f64fddce3e2a 100644
--- a/arch/arm/boot/dts/vf610-twr.dts
+++ b/arch/arm/boot/dts/vf610-twr.dts
@@ -129,13 +129,28 @@
&fec0 {
phy-mode = "rmii";
+ phy-handle = <&ethphy0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_fec0>;
status = "okay";
+
+ mdio {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ ethphy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+
+ ethphy1: ethernet-phy@1 {
+ reg = <1>;
+ };
+ };
};
&fec1 {
phy-mode = "rmii";
+ phy-handle = <&ethphy1>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_fec1>;
status = "okay";
diff --git a/arch/arm/boot/dts/zynq-parallella.dts b/arch/arm/boot/dts/zynq-parallella.dts
index ab1dc0a56cdd..174571232ea5 100644
--- a/arch/arm/boot/dts/zynq-parallella.dts
+++ b/arch/arm/boot/dts/zynq-parallella.dts
@@ -58,7 +58,7 @@
status = "okay";
isl9305: isl9305@68 {
- compatible = "isl,isl9305";
+ compatible = "isil,isl9305";
reg = <0x68>;
regulators {
diff --git a/arch/arm/configs/at91_dt_defconfig b/arch/arm/configs/at91_dt_defconfig
index a67375f24b21..f2670f638e97 100644
--- a/arch/arm/configs/at91_dt_defconfig
+++ b/arch/arm/configs/at91_dt_defconfig
@@ -15,15 +15,7 @@ CONFIG_MODULE_UNLOAD=y
# CONFIG_IOSCHED_CFQ is not set
CONFIG_ARCH_AT91=y
CONFIG_SOC_AT91RM9200=y
-CONFIG_SOC_AT91SAM9260=y
-CONFIG_SOC_AT91SAM9261=y
-CONFIG_SOC_AT91SAM9263=y
-CONFIG_SOC_AT91SAM9RL=y
-CONFIG_SOC_AT91SAM9G45=y
-CONFIG_SOC_AT91SAM9X5=y
-CONFIG_SOC_AT91SAM9N12=y
-CONFIG_MACH_AT91RM9200_DT=y
-CONFIG_MACH_AT91SAM9_DT=y
+CONFIG_SOC_AT91SAM9=y
CONFIG_AT91_TIMER_HZ=128
CONFIG_AEABI=y
CONFIG_UACCESS_WITH_MEMCPY=y
diff --git a/arch/arm/configs/exynos_defconfig b/arch/arm/configs/exynos_defconfig
index 5ef14de00a29..3d0c5d65c741 100644
--- a/arch/arm/configs/exynos_defconfig
+++ b/arch/arm/configs/exynos_defconfig
@@ -84,7 +84,8 @@ CONFIG_DEBUG_GPIO=y
CONFIG_POWER_SUPPLY=y
CONFIG_BATTERY_SBS=y
CONFIG_CHARGER_TPS65090=y
-# CONFIG_HWMON is not set
+CONFIG_HWMON=y
+CONFIG_SENSORS_LM90=y
CONFIG_THERMAL=y
CONFIG_EXYNOS_THERMAL=y
CONFIG_EXYNOS_THERMAL_CORE=y
@@ -109,11 +110,26 @@ CONFIG_REGULATOR_S2MPA01=y
CONFIG_REGULATOR_S2MPS11=y
CONFIG_REGULATOR_S5M8767=y
CONFIG_REGULATOR_TPS65090=y
+CONFIG_DRM=y
+CONFIG_DRM_BRIDGE=y
+CONFIG_DRM_PTN3460=y
+CONFIG_DRM_PS8622=y
+CONFIG_DRM_EXYNOS=y
+CONFIG_DRM_EXYNOS_FIMD=y
+CONFIG_DRM_EXYNOS_DP=y
+CONFIG_DRM_PANEL=y
+CONFIG_DRM_PANEL_SIMPLE=y
CONFIG_FB=y
CONFIG_FB_MODE_HELPERS=y
CONFIG_FB_SIMPLE=y
CONFIG_EXYNOS_VIDEO=y
CONFIG_EXYNOS_MIPI_DSI=y
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+CONFIG_LCD_PLATFORM=y
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+CONFIG_BACKLIGHT_GENERIC=y
+CONFIG_BACKLIGHT_PWM=y
CONFIG_FRAMEBUFFER_CONSOLE=y
CONFIG_FONTS=y
CONFIG_FONT_7x14=y
diff --git a/arch/arm/configs/iop32x_defconfig b/arch/arm/configs/iop32x_defconfig
index 4f2ec3ac138e..c3058da631da 100644
--- a/arch/arm/configs/iop32x_defconfig
+++ b/arch/arm/configs/iop32x_defconfig
@@ -106,6 +106,7 @@ CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_UART_8250=y
CONFIG_KEYS=y
CONFIG_KEYS_DEBUG_PROC_KEYS=y
CONFIG_CRYPTO_NULL=y
diff --git a/arch/arm/configs/iop33x_defconfig b/arch/arm/configs/iop33x_defconfig
index aa36128abca2..713faeee8cf4 100644
--- a/arch/arm/configs/iop33x_defconfig
+++ b/arch/arm/configs/iop33x_defconfig
@@ -87,5 +87,6 @@ CONFIG_DEBUG_KERNEL=y
# CONFIG_RCU_CPU_STALL_DETECTOR is not set
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_UART_8250=y
# CONFIG_CRYPTO_ANSI_CPRNG is not set
# CONFIG_CRC32 is not set
diff --git a/arch/arm/configs/ixp4xx_defconfig b/arch/arm/configs/ixp4xx_defconfig
index 1af665e847d1..24636cfdf6df 100644
--- a/arch/arm/configs/ixp4xx_defconfig
+++ b/arch/arm/configs/ixp4xx_defconfig
@@ -202,3 +202,4 @@ CONFIG_MAGIC_SYSRQ=y
CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_ERRORS=y
CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_UART_8250=y
diff --git a/arch/arm/configs/lager_defconfig b/arch/arm/configs/lager_defconfig
deleted file mode 100644
index a82afc916a89..000000000000
--- a/arch/arm/configs/lager_defconfig
+++ /dev/null
@@ -1,150 +0,0 @@
-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_PERF_EVENTS=y
-CONFIG_SLAB=y
-# CONFIG_LBDAF is not set
-# CONFIG_BLK_DEV_BSG is not set
-# CONFIG_IOSCHED_DEADLINE is not set
-# CONFIG_IOSCHED_CFQ is not set
-CONFIG_ARCH_SHMOBILE_LEGACY=y
-CONFIG_ARCH_R8A7790=y
-CONFIG_MACH_LAGER=y
-# CONFIG_SH_TIMER_TMU is not set
-# CONFIG_EM_TIMER_STI is not set
-CONFIG_ARM_ERRATA_430973=y
-CONFIG_ARM_ERRATA_458693=y
-CONFIG_ARM_ERRATA_460075=y
-CONFIG_ARM_ERRATA_743622=y
-CONFIG_ARM_ERRATA_754322=y
-CONFIG_PCI=y
-CONFIG_PCI_RCAR_GEN2=y
-CONFIG_PCI_RCAR_GEN2_PCIE=y
-CONFIG_HAVE_ARM_ARCH_TIMER=y
-CONFIG_AEABI=y
-# CONFIG_OABI_COMPAT is not set
-CONFIG_FORCE_MAX_ZONEORDER=13
-CONFIG_ZBOOT_ROM_TEXT=0x0
-CONFIG_ZBOOT_ROM_BSS=0x0
-CONFIG_ARM_APPENDED_DTB=y
-CONFIG_KEXEC=y
-CONFIG_AUTO_ZRELADDR=y
-CONFIG_VFP=y
-CONFIG_NEON=y
-# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
-CONFIG_PM=y
-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_DEVTMPFS=y
-CONFIG_DEVTMPFS_MOUNT=y
-CONFIG_MTD=y
-CONFIG_MTD_M25P80=y
-CONFIG_MTD_SPI_NOR=y
-CONFIG_BLK_DEV_SD=y
-CONFIG_ATA=y
-CONFIG_SATA_RCAR=y
-CONFIG_NETDEVICES=y
-# CONFIG_NET_CORE is not set
-# CONFIG_NET_VENDOR_ARC is not set
-# CONFIG_NET_CADENCE is not set
-# CONFIG_NET_VENDOR_BROADCOM 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_SH_ETH=y
-# CONFIG_NET_VENDOR_SEEQ is not set
-# CONFIG_NET_VENDOR_SMSC is not set
-# CONFIG_NET_VENDOR_STMICRO is not set
-# CONFIG_NET_VENDOR_VIA is not set
-# CONFIG_NET_VENDOR_WIZNET is not set
-# CONFIG_WLAN is not set
-# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
-CONFIG_INPUT_EVDEV=y
-# CONFIG_KEYBOARD_ATKBD is not set
-CONFIG_KEYBOARD_GPIO=y
-# CONFIG_INPUT_MOUSE is not set
-# CONFIG_SERIO is not set
-# CONFIG_LEGACY_PTYS is not set
-CONFIG_SERIAL_SH_SCI=y
-CONFIG_SERIAL_SH_SCI_NR_UARTS=10
-CONFIG_SERIAL_SH_SCI_CONSOLE=y
-# CONFIG_HW_RANDOM is not set
-CONFIG_I2C_GPIO=y
-CONFIG_I2C_SH_MOBILE=y
-CONFIG_I2C_RCAR=y
-CONFIG_SPI=y
-CONFIG_SPI_RSPI=y
-CONFIG_SPI_SH_MSIOF=y
-CONFIG_GPIO_SH_PFC=y
-CONFIG_GPIOLIB=y
-CONFIG_GPIO_RCAR=y
-# CONFIG_HWMON is not set
-CONFIG_THERMAL=y
-CONFIG_RCAR_THERMAL=y
-CONFIG_REGULATOR=y
-CONFIG_REGULATOR_FIXED_VOLTAGE=y
-CONFIG_REGULATOR_DA9210=y
-CONFIG_REGULATOR_GPIO=y
-CONFIG_MEDIA_SUPPORT=y
-CONFIG_MEDIA_CAMERA_SUPPORT=y
-CONFIG_V4L_PLATFORM_DRIVERS=y
-CONFIG_SOC_CAMERA=y
-CONFIG_SOC_CAMERA_PLATFORM=y
-CONFIG_VIDEO_RCAR_VIN=y
-# CONFIG_MEDIA_SUBDRV_AUTOSELECT is not set
-CONFIG_VIDEO_ADV7180=y
-CONFIG_DRM=y
-CONFIG_DRM_RCAR_DU=y
-CONFIG_SOUND=y
-CONFIG_SND=y
-CONFIG_SND_SOC=y
-CONFIG_SND_SOC_RCAR=y
-# CONFIG_USB_SUPPORT is not set
-CONFIG_MMC=y
-CONFIG_MMC_SDHI=y
-CONFIG_MMC_SH_MMCIF=y
-CONFIG_NEW_LEDS=y
-CONFIG_LEDS_CLASS=y
-CONFIG_LEDS_GPIO=y
-CONFIG_RTC_CLASS=y
-CONFIG_DMADEVICES=y
-CONFIG_SH_DMAE=y
-# CONFIG_IOMMU_SUPPORT is not set
-# CONFIG_DNOTIFY is not set
-CONFIG_MSDOS_FS=y
-CONFIG_VFAT_FS=y
-CONFIG_TMPFS=y
-CONFIG_CONFIGFS_FS=y
-# CONFIG_MISC_FILESYSTEMS is not set
-CONFIG_NFS_FS=y
-CONFIG_NFS_V3_ACL=y
-CONFIG_NFS_V4=y
-CONFIG_NFS_V4_1=y
-CONFIG_ROOT_NFS=y
-CONFIG_NLS_CODEPAGE_437=y
-CONFIG_NLS_ISO8859_1=y
-# CONFIG_ENABLE_WARN_DEPRECATED is not set
-# CONFIG_ENABLE_MUST_CHECK is not set
-# CONFIG_ARM_UNWIND is not set
-# CONFIG_CRYPTO_ANSI_CPRNG is not set
-# CONFIG_CRYPTO_HW is not set
diff --git a/arch/arm/configs/lpc32xx_defconfig b/arch/arm/configs/lpc32xx_defconfig
index 9f56ca3985ae..c100b7df5441 100644
--- a/arch/arm/configs/lpc32xx_defconfig
+++ b/arch/arm/configs/lpc32xx_defconfig
@@ -204,6 +204,7 @@ CONFIG_DEBUG_INFO=y
# CONFIG_FTRACE is not set
# CONFIG_ARM_UNWIND is not set
CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_UART_8250=y
CONFIG_EARLY_PRINTK=y
CONFIG_CRYPTO_ANSI_CPRNG=y
# CONFIG_CRYPTO_HW is not set
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig
index bc393b7e5ece..444685c44055 100644
--- a/arch/arm/configs/multi_v7_defconfig
+++ b/arch/arm/configs/multi_v7_defconfig
@@ -456,6 +456,7 @@ CONFIG_OMAP_USB2=y
CONFIG_TI_PIPE3=y
CONFIG_PHY_MIPHY365X=y
CONFIG_PHY_STIH41X_USB=y
+CONFIG_PHY_STIH407_USB=y
CONFIG_PHY_SUN4I_USB=y
CONFIG_EXT4_FS=y
CONFIG_AUTOFS4_FS=y
diff --git a/arch/arm/configs/mv78xx0_defconfig b/arch/arm/configs/mv78xx0_defconfig
index 0dae1c1f007a..85d10d2e3d66 100644
--- a/arch/arm/configs/mv78xx0_defconfig
+++ b/arch/arm/configs/mv78xx0_defconfig
@@ -132,6 +132,7 @@ CONFIG_SYSCTL_SYSCALL_CHECK=y
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_ERRORS=y
CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_UART_8250=y
CONFIG_CRYPTO_CBC=m
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_PCBC=m
diff --git a/arch/arm/configs/mvebu_v7_defconfig b/arch/arm/configs/mvebu_v7_defconfig
index 627accea72fb..2400b9f52403 100644
--- a/arch/arm/configs/mvebu_v7_defconfig
+++ b/arch/arm/configs/mvebu_v7_defconfig
@@ -112,6 +112,7 @@ CONFIG_LEDS_TRIGGER_HEARTBEAT=y
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_S35390A=y
CONFIG_RTC_DRV_MV=y
+CONFIG_RTC_DRV_ARMADA38X=y
CONFIG_DMADEVICES=y
CONFIG_MV_XOR=y
# CONFIG_IOMMU_SUPPORT is not set
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig
index c2c3a852af9f..667d9d52aa01 100644
--- a/arch/arm/configs/omap2plus_defconfig
+++ b/arch/arm/configs/omap2plus_defconfig
@@ -68,7 +68,7 @@ CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND=y
CONFIG_CPU_FREQ_GOV_POWERSAVE=y
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
-CONFIG_GENERIC_CPUFREQ_CPU0=y
+CONFIG_CPUFREQ_DT=y
# CONFIG_ARM_OMAP2PLUS_CPUFREQ is not set
CONFIG_CPU_IDLE=y
CONFIG_BINFMT_MISC=y
diff --git a/arch/arm/configs/orion5x_defconfig b/arch/arm/configs/orion5x_defconfig
index 952430d9e2d9..855143fac6bd 100644
--- a/arch/arm/configs/orion5x_defconfig
+++ b/arch/arm/configs/orion5x_defconfig
@@ -156,6 +156,7 @@ CONFIG_LATENCYTOP=y
# CONFIG_FTRACE is not set
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_UART_8250=y
CONFIG_CRYPTO_CBC=m
CONFIG_CRYPTO_ECB=m
CONFIG_CRYPTO_PCBC=m
diff --git a/arch/arm/configs/rpc_defconfig b/arch/arm/configs/rpc_defconfig
index 00515ef9782d..89631795a915 100644
--- a/arch/arm/configs/rpc_defconfig
+++ b/arch/arm/configs/rpc_defconfig
@@ -131,3 +131,4 @@ CONFIG_DEBUG_KERNEL=y
CONFIG_DEBUG_USER=y
CONFIG_DEBUG_ERRORS=y
CONFIG_DEBUG_LL=y
+CONFIG_DEBUG_LL_UART_8250=y
diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig
index 3df6ca0c1d1f..e4a6c5e9174d 100644
--- a/arch/arm/configs/shmobile_defconfig
+++ b/arch/arm/configs/shmobile_defconfig
@@ -17,7 +17,6 @@ CONFIG_ARCH_R8A7779=y
CONFIG_ARCH_R8A7790=y
CONFIG_ARCH_R8A7791=y
CONFIG_ARCH_R8A7794=y
-CONFIG_MACH_LAGER=y
CONFIG_MACH_MARZEN=y
# CONFIG_SWP_EMULATE is not set
CONFIG_CPU_BPREDICT_DISABLE=y
diff --git a/arch/arm/include/asm/bitrev.h b/arch/arm/include/asm/bitrev.h
new file mode 100644
index 000000000000..ec291c350ea3
--- /dev/null
+++ b/arch/arm/include/asm/bitrev.h
@@ -0,0 +1,20 @@
+#ifndef __ASM_BITREV_H
+#define __ASM_BITREV_H
+
+static __always_inline __attribute_const__ u32 __arch_bitrev32(u32 x)
+{
+ __asm__ ("rbit %0, %1" : "=r" (x) : "r" (x));
+ return x;
+}
+
+static __always_inline __attribute_const__ u16 __arch_bitrev16(u16 x)
+{
+ return __arch_bitrev32((u32)x) >> 16;
+}
+
+static __always_inline __attribute_const__ u8 __arch_bitrev8(u8 x)
+{
+ return __arch_bitrev32((u32)x) >> 24;
+}
+
+#endif
diff --git a/arch/arm/include/asm/compiler.h b/arch/arm/include/asm/compiler.h
index 8155db2f7fa1..29fe85e59439 100644
--- a/arch/arm/include/asm/compiler.h
+++ b/arch/arm/include/asm/compiler.h
@@ -8,8 +8,21 @@
* This string is meant to be concatenated with the inline asm string and
* will cause compilation to stop on mismatch.
* (for details, see gcc PR 15089)
+ * For compatibility with clang, we have to specifically take the equivalence
+ * of 'r11' <-> 'fp' and 'r12' <-> 'ip' into account as well.
*/
-#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t"
+#define __asmeq(x, y) \
+ ".ifnc " x "," y "; " \
+ ".ifnc " x y ",fpr11; " \
+ ".ifnc " x y ",r11fp; " \
+ ".ifnc " x y ",ipr12; " \
+ ".ifnc " x y ",r12ip; " \
+ ".err; " \
+ ".endif; " \
+ ".endif; " \
+ ".endif; " \
+ ".endif; " \
+ ".endif\n\t"
#endif /* __ASM_ARM_COMPILER_H */
diff --git a/arch/arm/kernel/insn.h b/arch/arm/include/asm/insn.h
index e96065da4dae..e96065da4dae 100644
--- a/arch/arm/kernel/insn.h
+++ b/arch/arm/include/asm/insn.h
diff --git a/arch/arm/include/asm/kprobes.h b/arch/arm/include/asm/kprobes.h
index 49fa0dfaad33..3ea9be559726 100644
--- a/arch/arm/include/asm/kprobes.h
+++ b/arch/arm/include/asm/kprobes.h
@@ -22,7 +22,6 @@
#define __ARCH_WANT_KPROBES_INSN_SLOT
#define MAX_INSN_SIZE 2
-#define MAX_STACK_SIZE 64 /* 32 would probably be OK */
#define flush_insn_slot(p) do { } while (0)
#define kretprobe_blacklist_size 0
@@ -51,5 +50,37 @@ int kprobe_fault_handler(struct pt_regs *regs, unsigned int fsr);
int kprobe_exceptions_notify(struct notifier_block *self,
unsigned long val, void *data);
+/* optinsn template addresses */
+extern __visible kprobe_opcode_t optprobe_template_entry;
+extern __visible kprobe_opcode_t optprobe_template_val;
+extern __visible kprobe_opcode_t optprobe_template_call;
+extern __visible kprobe_opcode_t optprobe_template_end;
+extern __visible kprobe_opcode_t optprobe_template_sub_sp;
+extern __visible kprobe_opcode_t optprobe_template_add_sp;
+extern __visible kprobe_opcode_t optprobe_template_restore_begin;
+extern __visible kprobe_opcode_t optprobe_template_restore_orig_insn;
+extern __visible kprobe_opcode_t optprobe_template_restore_end;
+
+#define MAX_OPTIMIZED_LENGTH 4
+#define MAX_OPTINSN_SIZE \
+ ((unsigned long)&optprobe_template_end - \
+ (unsigned long)&optprobe_template_entry)
+#define RELATIVEJUMP_SIZE 4
+
+struct arch_optimized_insn {
+ /*
+ * copy of the original instructions.
+ * Different from x86, ARM kprobe_opcode_t is u32.
+ */
+#define MAX_COPIED_INSN DIV_ROUND_UP(RELATIVEJUMP_SIZE, sizeof(kprobe_opcode_t))
+ kprobe_opcode_t copied_insn[MAX_COPIED_INSN];
+ /* detour code buffer */
+ kprobe_opcode_t *insn;
+ /*
+ * We always copy one instruction on ARM,
+ * so size will always be 4, and unlike x86, there is no
+ * need for a size field.
+ */
+};
#endif /* _ARM_KPROBES_H */
diff --git a/arch/arm/include/asm/kvm_asm.h b/arch/arm/include/asm/kvm_asm.h
index 3a67bec72d0c..25410b2d8bc1 100644
--- a/arch/arm/include/asm/kvm_asm.h
+++ b/arch/arm/include/asm/kvm_asm.h
@@ -96,6 +96,7 @@ extern char __kvm_hyp_code_end[];
extern void __kvm_flush_vm_context(void);
extern void __kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa);
+extern void __kvm_tlb_flush_vmid(struct kvm *kvm);
extern int __kvm_vcpu_run(struct kvm_vcpu *vcpu);
#endif
diff --git a/arch/arm/include/asm/kvm_emulate.h b/arch/arm/include/asm/kvm_emulate.h
index 66ce17655bb9..a9c80a2ea1a7 100644
--- a/arch/arm/include/asm/kvm_emulate.h
+++ b/arch/arm/include/asm/kvm_emulate.h
@@ -23,6 +23,7 @@
#include <asm/kvm_asm.h>
#include <asm/kvm_mmio.h>
#include <asm/kvm_arm.h>
+#include <asm/cputype.h>
unsigned long *vcpu_reg(struct kvm_vcpu *vcpu, u8 reg_num);
unsigned long *vcpu_spsr(struct kvm_vcpu *vcpu);
@@ -38,6 +39,16 @@ static inline void vcpu_reset_hcr(struct kvm_vcpu *vcpu)
vcpu->arch.hcr = HCR_GUEST_MASK;
}
+static inline unsigned long vcpu_get_hcr(struct kvm_vcpu *vcpu)
+{
+ return vcpu->arch.hcr;
+}
+
+static inline void vcpu_set_hcr(struct kvm_vcpu *vcpu, unsigned long hcr)
+{
+ vcpu->arch.hcr = hcr;
+}
+
static inline bool vcpu_mode_is_32bit(struct kvm_vcpu *vcpu)
{
return 1;
@@ -167,9 +178,9 @@ static inline u32 kvm_vcpu_hvc_get_imm(struct kvm_vcpu *vcpu)
return kvm_vcpu_get_hsr(vcpu) & HSR_HVC_IMM_MASK;
}
-static inline unsigned long kvm_vcpu_get_mpidr(struct kvm_vcpu *vcpu)
+static inline unsigned long kvm_vcpu_get_mpidr_aff(struct kvm_vcpu *vcpu)
{
- return vcpu->arch.cp15[c0_MPIDR];
+ return vcpu->arch.cp15[c0_MPIDR] & MPIDR_HWID_BITMASK;
}
static inline void kvm_vcpu_set_be(struct kvm_vcpu *vcpu)
diff --git a/arch/arm/include/asm/kvm_host.h b/arch/arm/include/asm/kvm_host.h
index 254e0650e48b..41008cd7c53f 100644
--- a/arch/arm/include/asm/kvm_host.h
+++ b/arch/arm/include/asm/kvm_host.h
@@ -68,6 +68,7 @@ struct kvm_arch {
/* Interrupt controller */
struct vgic_dist vgic;
+ int max_vcpus;
};
#define KVM_NR_MEM_OBJS 40
@@ -125,9 +126,6 @@ struct kvm_vcpu_arch {
* Anything that is not used directly from assembly code goes
* here.
*/
- /* dcache set/way operation pending */
- int last_pcpu;
- cpumask_t require_dcache_flush;
/* Don't run the guest on this vcpu */
bool pause;
@@ -147,6 +145,7 @@ struct kvm_vm_stat {
};
struct kvm_vcpu_stat {
+ u32 halt_successful_poll;
u32 halt_wakeup;
};
@@ -234,6 +233,10 @@ static inline void vgic_arch_setup(const struct vgic_params *vgic)
int kvm_perf_init(void);
int kvm_perf_teardown(void);
+void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot);
+
+struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr);
+
static inline void kvm_arch_hardware_disable(void) {}
static inline void kvm_arch_hardware_unsetup(void) {}
static inline void kvm_arch_sync_events(struct kvm *kvm) {}
diff --git a/arch/arm/include/asm/kvm_mmio.h b/arch/arm/include/asm/kvm_mmio.h
index adcc0d7d3175..3f83db2f6cf0 100644
--- a/arch/arm/include/asm/kvm_mmio.h
+++ b/arch/arm/include/asm/kvm_mmio.h
@@ -37,6 +37,7 @@ struct kvm_exit_mmio {
u8 data[8];
u32 len;
bool is_write;
+ void *private;
};
static inline void kvm_prepare_mmio(struct kvm_run *run,
diff --git a/arch/arm/include/asm/kvm_mmu.h b/arch/arm/include/asm/kvm_mmu.h
index 63e0ecc04901..37ca2a4c6f09 100644
--- a/arch/arm/include/asm/kvm_mmu.h
+++ b/arch/arm/include/asm/kvm_mmu.h
@@ -44,6 +44,7 @@
#ifndef __ASSEMBLY__
+#include <linux/highmem.h>
#include <asm/cacheflush.h>
#include <asm/pgalloc.h>
@@ -114,6 +115,27 @@ static inline void kvm_set_s2pmd_writable(pmd_t *pmd)
pmd_val(*pmd) |= L_PMD_S2_RDWR;
}
+static inline void kvm_set_s2pte_readonly(pte_t *pte)
+{
+ pte_val(*pte) = (pte_val(*pte) & ~L_PTE_S2_RDWR) | L_PTE_S2_RDONLY;
+}
+
+static inline bool kvm_s2pte_readonly(pte_t *pte)
+{
+ return (pte_val(*pte) & L_PTE_S2_RDWR) == L_PTE_S2_RDONLY;
+}
+
+static inline void kvm_set_s2pmd_readonly(pmd_t *pmd)
+{
+ pmd_val(*pmd) = (pmd_val(*pmd) & ~L_PMD_S2_RDWR) | L_PMD_S2_RDONLY;
+}
+
+static inline bool kvm_s2pmd_readonly(pmd_t *pmd)
+{
+ return (pmd_val(*pmd) & L_PMD_S2_RDWR) == L_PMD_S2_RDONLY;
+}
+
+
/* Open coded p*d_addr_end that can deal with 64bit addresses */
#define kvm_pgd_addr_end(addr, end) \
({ u64 __boundary = ((addr) + PGDIR_SIZE) & PGDIR_MASK; \
@@ -161,13 +183,10 @@ static inline bool vcpu_has_cache_enabled(struct kvm_vcpu *vcpu)
return (vcpu->arch.cp15[c1_SCTLR] & 0b101) == 0b101;
}
-static inline void coherent_cache_guest_page(struct kvm_vcpu *vcpu, hva_t hva,
- unsigned long size,
- bool ipa_uncached)
+static inline void __coherent_cache_guest_page(struct kvm_vcpu *vcpu, pfn_t pfn,
+ unsigned long size,
+ bool ipa_uncached)
{
- if (!vcpu_has_cache_enabled(vcpu) || ipa_uncached)
- kvm_flush_dcache_to_poc((void *)hva, size);
-
/*
* If we are going to insert an instruction page and the icache is
* either VIPT or PIPT, there is a potential problem where the host
@@ -179,18 +198,77 @@ static inline void coherent_cache_guest_page(struct kvm_vcpu *vcpu, hva_t hva,
*
* VIVT caches are tagged using both the ASID and the VMID and doesn't
* need any kind of flushing (DDI 0406C.b - Page B3-1392).
+ *
+ * We need to do this through a kernel mapping (using the
+ * user-space mapping has proved to be the wrong
+ * solution). For that, we need to kmap one page at a time,
+ * and iterate over the range.
*/
- if (icache_is_pipt()) {
- __cpuc_coherent_user_range(hva, hva + size);
- } else if (!icache_is_vivt_asid_tagged()) {
+
+ bool need_flush = !vcpu_has_cache_enabled(vcpu) || ipa_uncached;
+
+ VM_BUG_ON(size & PAGE_MASK);
+
+ if (!need_flush && !icache_is_pipt())
+ goto vipt_cache;
+
+ while (size) {
+ void *va = kmap_atomic_pfn(pfn);
+
+ if (need_flush)
+ kvm_flush_dcache_to_poc(va, PAGE_SIZE);
+
+ if (icache_is_pipt())
+ __cpuc_coherent_user_range((unsigned long)va,
+ (unsigned long)va + PAGE_SIZE);
+
+ size -= PAGE_SIZE;
+ pfn++;
+
+ kunmap_atomic(va);
+ }
+
+vipt_cache:
+ if (!icache_is_pipt() && !icache_is_vivt_asid_tagged()) {
/* any kind of VIPT cache */
__flush_icache_all();
}
}
+static inline void __kvm_flush_dcache_pte(pte_t pte)
+{
+ void *va = kmap_atomic(pte_page(pte));
+
+ kvm_flush_dcache_to_poc(va, PAGE_SIZE);
+
+ kunmap_atomic(va);
+}
+
+static inline void __kvm_flush_dcache_pmd(pmd_t pmd)
+{
+ unsigned long size = PMD_SIZE;
+ pfn_t pfn = pmd_pfn(pmd);
+
+ while (size) {
+ void *va = kmap_atomic_pfn(pfn);
+
+ kvm_flush_dcache_to_poc(va, PAGE_SIZE);
+
+ pfn++;
+ size -= PAGE_SIZE;
+
+ kunmap_atomic(va);
+ }
+}
+
+static inline void __kvm_flush_dcache_pud(pud_t pud)
+{
+}
+
#define kvm_virt_to_phys(x) virt_to_idmap((unsigned long)(x))
-void stage2_flush_vm(struct kvm *kvm);
+void kvm_set_way_flush(struct kvm_vcpu *vcpu);
+void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled);
#endif /* !__ASSEMBLY__ */
diff --git a/arch/arm/include/asm/mach/irda.h b/arch/arm/include/asm/mach/irda.h
deleted file mode 100644
index 38f77b5e56cf..000000000000
--- a/arch/arm/include/asm/mach/irda.h
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * arch/arm/include/asm/mach/irda.h
- *
- * Copyright (C) 2004 Russell King.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __ASM_ARM_MACH_IRDA_H
-#define __ASM_ARM_MACH_IRDA_H
-
-struct irda_platform_data {
- int (*startup)(struct device *);
- void (*shutdown)(struct device *);
- int (*set_power)(struct device *, unsigned int state);
- void (*set_speed)(struct device *, unsigned int speed);
-};
-
-#endif
diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 8292b5f81e23..28b9bb35949e 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -19,9 +19,6 @@ struct pci_bus;
struct device;
struct hw_pci {
-#ifdef CONFIG_PCI_DOMAINS
- int domain;
-#endif
#ifdef CONFIG_PCI_MSI
struct msi_controller *msi_ctrl;
#endif
@@ -45,9 +42,6 @@ struct hw_pci {
* Per-controller structure
*/
struct pci_sys_data {
-#ifdef CONFIG_PCI_DOMAINS
- int domain;
-#endif
#ifdef CONFIG_PCI_MSI
struct msi_controller *msi_ctrl;
#endif
diff --git a/arch/arm/include/asm/outercache.h b/arch/arm/include/asm/outercache.h
index 891a56b35bcf..563b92fc2f41 100644
--- a/arch/arm/include/asm/outercache.h
+++ b/arch/arm/include/asm/outercache.h
@@ -23,6 +23,8 @@
#include <linux/types.h>
+struct l2x0_regs;
+
struct outer_cache_fns {
void (*inv_range)(unsigned long, unsigned long);
void (*clean_range)(unsigned long, unsigned long);
@@ -36,6 +38,7 @@ struct outer_cache_fns {
/* This is an ARM L2C thing */
void (*write_sec)(unsigned long, unsigned);
+ void (*configure)(const struct l2x0_regs *);
};
extern struct outer_cache_fns outer_cache;
diff --git a/arch/arm/kernel/patch.h b/arch/arm/include/asm/patch.h
index 77e054c2f6cd..77e054c2f6cd 100644
--- a/arch/arm/kernel/patch.h
+++ b/arch/arm/include/asm/patch.h
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
index 7e95d8535e24..585dc33a7a24 100644
--- a/arch/arm/include/asm/pci.h
+++ b/arch/arm/include/asm/pci.h
@@ -18,13 +18,6 @@ static inline int pcibios_assign_all_busses(void)
}
#ifdef CONFIG_PCI_DOMAINS
-static inline int pci_domain_nr(struct pci_bus *bus)
-{
- struct pci_sys_data *root = bus->sysdata;
-
- return root->domain;
-}
-
static inline int pci_proc_domain(struct pci_bus *bus)
{
return pci_domain_nr(bus);
diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h
index f0279411847d..bfd662e49a25 100644
--- a/arch/arm/include/asm/pgtable-2level.h
+++ b/arch/arm/include/asm/pgtable-2level.h
@@ -10,6 +10,8 @@
#ifndef _ASM_PGTABLE_2LEVEL_H
#define _ASM_PGTABLE_2LEVEL_H
+#define __PAGETABLE_PMD_FOLDED
+
/*
* Hardware-wise, we have a two level page table structure, where the first
* level has 4096 entries, and the second level has 256 entries. Each entry
@@ -118,7 +120,6 @@
#define L_PTE_VALID (_AT(pteval_t, 1) << 0) /* Valid */
#define L_PTE_PRESENT (_AT(pteval_t, 1) << 0)
#define L_PTE_YOUNG (_AT(pteval_t, 1) << 1)
-#define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
#define L_PTE_DIRTY (_AT(pteval_t, 1) << 6)
#define L_PTE_RDONLY (_AT(pteval_t, 1) << 7)
#define L_PTE_USER (_AT(pteval_t, 1) << 8)
diff --git a/arch/arm/include/asm/pgtable-3level.h b/arch/arm/include/asm/pgtable-3level.h
index a31ecdad4b59..a745a2a53853 100644
--- a/arch/arm/include/asm/pgtable-3level.h
+++ b/arch/arm/include/asm/pgtable-3level.h
@@ -77,7 +77,6 @@
*/
#define L_PTE_VALID (_AT(pteval_t, 1) << 0) /* Valid */
#define L_PTE_PRESENT (_AT(pteval_t, 3) << 0) /* Present */
-#define L_PTE_FILE (_AT(pteval_t, 1) << 2) /* only when !PRESENT */
#define L_PTE_USER (_AT(pteval_t, 1) << 6) /* AP[1] */
#define L_PTE_SHARED (_AT(pteval_t, 3) << 8) /* SH[1:0], inner shareable */
#define L_PTE_YOUNG (_AT(pteval_t, 1) << 10) /* AF */
@@ -130,6 +129,7 @@
#define L_PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[1] */
#define L_PTE_S2_RDWR (_AT(pteval_t, 3) << 6) /* HAP[2:1] */
+#define L_PMD_S2_RDONLY (_AT(pmdval_t, 1) << 6) /* HAP[1] */
#define L_PMD_S2_RDWR (_AT(pmdval_t, 3) << 6) /* HAP[2:1] */
/*
@@ -258,7 +258,10 @@ PMD_BIT_FUNC(mkyoung, |= PMD_SECT_AF);
#define mk_pmd(page,prot) pfn_pmd(page_to_pfn(page),prot)
/* represent a notpresent pmd by zero, this is used by pmdp_invalidate */
-#define pmd_mknotpresent(pmd) (__pmd(0))
+static inline pmd_t pmd_mknotpresent(pmd_t pmd)
+{
+ return __pmd(0);
+}
static inline pmd_t pmd_modify(pmd_t pmd, pgprot_t newprot)
{
diff --git a/arch/arm/include/asm/pgtable-nommu.h b/arch/arm/include/asm/pgtable-nommu.h
index 0642228ff785..add094d09e3e 100644
--- a/arch/arm/include/asm/pgtable-nommu.h
+++ b/arch/arm/include/asm/pgtable-nommu.h
@@ -54,8 +54,6 @@
typedef pte_t *pte_addr_t;
-static inline int pte_file(pte_t pte) { return 0; }
-
/*
* ZERO_PAGE is a global shared page that is always zero: used
* for zero-mapped memory areas etc..
@@ -87,7 +85,7 @@ extern unsigned int kobjsize(const void *objp);
#define VMALLOC_START 0UL
#define VMALLOC_END 0xffffffffUL
-#define FIRST_USER_ADDRESS (0)
+#define FIRST_USER_ADDRESS 0UL
#include <asm-generic/pgtable.h>
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h
index d5cac545ba33..f40354198bad 100644
--- a/arch/arm/include/asm/pgtable.h
+++ b/arch/arm/include/asm/pgtable.h
@@ -318,12 +318,12 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
*
* 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
* 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- * <--------------- offset ----------------------> < type -> 0 0 0
+ * <--------------- offset ------------------------> < type -> 0 0
*
- * This gives us up to 31 swap files and 64GB per swap file. Note that
+ * This gives us up to 31 swap files and 128GB per swap file. Note that
* the offset field is always non-zero.
*/
-#define __SWP_TYPE_SHIFT 3
+#define __SWP_TYPE_SHIFT 2
#define __SWP_TYPE_BITS 5
#define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1)
#define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT)
@@ -342,20 +342,6 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
*/
#define MAX_SWAPFILES_CHECK() BUILD_BUG_ON(MAX_SWAPFILES_SHIFT > __SWP_TYPE_BITS)
-/*
- * Encode and decode a file entry. File entries are stored in the Linux
- * page tables as follows:
- *
- * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1
- * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
- * <----------------------- offset ------------------------> 1 0 0
- */
-#define pte_file(pte) (pte_val(pte) & L_PTE_FILE)
-#define pte_to_pgoff(x) (pte_val(x) >> 3)
-#define pgoff_to_pte(x) __pte(((x) << 3) | L_PTE_FILE)
-
-#define PTE_FILE_MAX_BITS 29
-
/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */
/* FIXME: this is not correct */
#define kern_addr_valid(addr) (1)
diff --git a/arch/arm/include/asm/probes.h b/arch/arm/include/asm/probes.h
index 806cfe622a9e..1e5b9bb92270 100644
--- a/arch/arm/include/asm/probes.h
+++ b/arch/arm/include/asm/probes.h
@@ -19,6 +19,8 @@
#ifndef _ASM_PROBES_H
#define _ASM_PROBES_H
+#ifndef __ASSEMBLY__
+
typedef u32 probes_opcode_t;
struct arch_probes_insn;
@@ -38,6 +40,19 @@ struct arch_probes_insn {
probes_check_cc *insn_check_cc;
probes_insn_singlestep_t *insn_singlestep;
probes_insn_fn_t *insn_fn;
+ int stack_space;
+ unsigned long register_usage_flags;
+ bool kprobe_direct_exec;
};
+#endif /* __ASSEMBLY__ */
+
+/*
+ * We assume one instruction can consume at most 64 bytes stack, which is
+ * 'push {r0-r15}'. Instructions consume more or unknown stack space like
+ * 'str r0, [sp, #-80]' and 'str r0, [sp, r1]' should be prohibit to probe.
+ * Both kprobe and jprobe use this macro.
+ */
+#define MAX_STACK_SIZE 64
+
#endif
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
index d890e41f5520..72812a1f3d1c 100644
--- a/arch/arm/include/asm/thread_info.h
+++ b/arch/arm/include/asm/thread_info.h
@@ -68,7 +68,6 @@ struct thread_info {
#ifdef CONFIG_ARM_THUMBEE
unsigned long thumbee_state; /* ThumbEE Handler Base register */
#endif
- struct restart_block restart_block;
};
#define INIT_THREAD_INFO(tsk) \
@@ -81,9 +80,6 @@ struct thread_info {
.cpu_domain = domain_val(DOMAIN_USER, DOMAIN_MANAGER) | \
domain_val(DOMAIN_KERNEL, DOMAIN_MANAGER) | \
domain_val(DOMAIN_IO, DOMAIN_CLIENT), \
- .restart_block = { \
- .fn = do_no_restart_syscall, \
- }, \
}
#define init_thread_info (init_thread_union.thread_info)
diff --git a/arch/arm/include/asm/xen/page.h b/arch/arm/include/asm/xen/page.h
index 68c739b3fdf4..2f7e6ff67d51 100644
--- a/arch/arm/include/asm/xen/page.h
+++ b/arch/arm/include/asm/xen/page.h
@@ -92,7 +92,7 @@ extern int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
struct page **pages, unsigned int count);
extern int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
- struct gnttab_map_grant_ref *kmap_ops,
+ struct gnttab_unmap_grant_ref *kunmap_ops,
struct page **pages, unsigned int count);
bool __set_phys_to_machine(unsigned long pfn, unsigned long mfn);
diff --git a/arch/arm/mach-at91/include/mach/debug-macro.S b/arch/arm/include/debug/at91.S
index 2103a90f2261..80a6501b4d50 100644
--- a/arch/arm/mach-at91/include/mach/debug-macro.S
+++ b/arch/arm/include/debug/at91.S
@@ -1,6 +1,4 @@
/*
- * arch/arm/mach-at91/include/mach/debug-macro.S
- *
* Copyright (C) 2003-2005 SAN People
*
* Debugging macro include header
@@ -11,18 +9,23 @@
*
*/
-#include <mach/hardware.h>
-#include <mach/at91_dbgu.h>
-
#if defined(CONFIG_AT91_DEBUG_LL_DBGU0)
-#define AT91_DBGU AT91_BASE_DBGU0
+#define AT91_DBGU 0xfffff200 /* AT91_BASE_DBGU0 */
#elif defined(CONFIG_AT91_DEBUG_LL_DBGU1)
-#define AT91_DBGU AT91_BASE_DBGU1
+#define AT91_DBGU 0xffffee00 /* AT91_BASE_DBGU1 */
#else
/* On sama5d4, use USART3 as low level serial console */
-#define AT91_DBGU SAMA5D4_BASE_USART3
+#define AT91_DBGU 0xfc00c000 /* SAMA5D4_BASE_USART3 */
#endif
+/* Keep in sync with mach-at91/include/mach/hardware.h */
+#define AT91_IO_P2V(x) ((x) - 0x01000000)
+
+#define AT91_DBGU_SR (0x14) /* Status Register */
+#define AT91_DBGU_THR (0x1c) /* Transmitter Holding Register */
+#define AT91_DBGU_TXRDY (1 << 1) /* Transmitter Ready */
+#define AT91_DBGU_TXEMPTY (1 << 9) /* Transmitter Empty */
+
.macro addruart, rp, rv, tmp
ldr \rp, =AT91_DBGU @ System peripherals (phys address)
ldr \rv, =AT91_IO_P2V(AT91_DBGU) @ System peripherals (virt address)
diff --git a/arch/arm/include/debug/digicolor.S b/arch/arm/include/debug/digicolor.S
new file mode 100644
index 000000000000..c9517150766a
--- /dev/null
+++ b/arch/arm/include/debug/digicolor.S
@@ -0,0 +1,35 @@
+/*
+ * Debugging macro include header for Conexant Digicolor USART
+ *
+ * Copyright (C) 2014 Paradox Innovation Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+*/
+
+#define UA0_STATUS 0x0742
+#define UA0_EMI_REC 0x0744
+
+#define UA0_STATUS_TX_READY 0x40
+
+#ifdef CONFIG_DEBUG_UART_PHYS
+ .macro addruart, rp, rv, tmp
+ ldr \rp, =CONFIG_DEBUG_UART_PHYS
+ ldr \rv, =CONFIG_DEBUG_UART_VIRT
+ .endm
+#endif
+
+ .macro senduart,rd,rx
+ strb \rd, [\rx, #UA0_EMI_REC]
+ .endm
+
+ .macro waituart,rd,rx
+ .endm
+
+ .macro busyuart,rd,rx
+1001: ldrb \rd, [\rx, #UA0_STATUS]
+ tst \rd, #UA0_STATUS_TX_READY
+ beq 1001b
+ .endm
diff --git a/arch/arm/mach-ks8695/include/mach/debug-macro.S b/arch/arm/include/debug/ks8695.S
index a79e48981202..961da1f32ab3 100644
--- a/arch/arm/mach-ks8695/include/mach/debug-macro.S
+++ b/arch/arm/include/debug/ks8695.S
@@ -1,5 +1,5 @@
/*
- * arch/arm/mach-ks8695/include/mach/debug-macro.S
+ * arch/arm/include/debug/ks8695.S
*
* Copyright (C) 2006 Ben Dooks <ben@simtec.co.uk>
* Copyright (C) 2006 Simtec Electronics
@@ -11,8 +11,12 @@
* published by the Free Software Foundation.
*/
-#include <mach/hardware.h>
-#include <mach/regs-uart.h>
+#define KS8695_UART_PA 0x03ffe000
+#define KS8695_UART_VA 0xf00fe000
+#define KS8695_URTH (0x04)
+#define KS8695_URLS (0x14)
+#define URLS_URTE (1 << 6)
+#define URLS_URTHRE (1 << 5)
.macro addruart, rp, rv, tmp
ldr \rp, =KS8695_UART_PA @ physical base address
diff --git a/arch/arm/include/debug/msm.S b/arch/arm/include/debug/msm.S
index 9ef57612811d..e55a9426b496 100644
--- a/arch/arm/include/debug/msm.S
+++ b/arch/arm/include/debug/msm.S
@@ -23,6 +23,7 @@
.endm
.macro senduart, rd, rx
+ARM_BE8(rev \rd, \rd )
#ifdef CONFIG_DEBUG_QCOM_UARTDM
@ Write the 1 character to UARTDM_TF
str \rd, [\rx, #0x70]
@@ -35,24 +36,29 @@
#ifdef CONFIG_DEBUG_QCOM_UARTDM
@ check for TX_EMT in UARTDM_SR
ldr \rd, [\rx, #0x08]
+ARM_BE8(rev \rd, \rd )
tst \rd, #0x08
bne 1002f
@ wait for TXREADY in UARTDM_ISR
1001: ldr \rd, [\rx, #0x14]
+ARM_BE8(rev \rd, \rd )
tst \rd, #0x80
beq 1001b
1002:
@ Clear TX_READY by writing to the UARTDM_CR register
mov \rd, #0x300
+ARM_BE8(rev \rd, \rd )
str \rd, [\rx, #0x10]
@ Write 0x1 to NCF register
mov \rd, #0x1
+ARM_BE8(rev \rd, \rd )
str \rd, [\rx, #0x40]
@ UARTDM reg. Read to induce delay
ldr \rd, [\rx, #0x08]
#else
@ wait for TX_READY
1001: ldr \rd, [\rx, #0x08]
+ARM_BE8(rev \rd, \rd )
tst \rd, #0x04
beq 1001b
#endif
diff --git a/arch/arm/mach-netx/include/mach/debug-macro.S b/arch/arm/include/debug/netx.S
index 247781e096e2..81e1b2af70f7 100644
--- a/arch/arm/mach-netx/include/mach/debug-macro.S
+++ b/arch/arm/include/debug/netx.S
@@ -1,5 +1,4 @@
-/* arch/arm/mach-netx/include/mach/debug-macro.S
- *
+/*
* Debugging macro include header
*
* Copyright (C) 1994-1999 Russell King
@@ -11,26 +10,27 @@
*
*/
-#include "hardware.h"
+#define UART_DATA 0
+#define UART_FLAG 0x18
+#define UART_FLAG_BUSY (1 << 3)
.macro addruart, rp, rv, tmp
- mov \rp, #0x00000a00
- orr \rv, \rp, #io_p2v(0x00100000) @ virtual
- orr \rp, \rp, #0x00100000 @ physical
+ ldr \rp, =CONFIG_DEBUG_UART_PHYS
+ ldr \rv, =CONFIG_DEBUG_UART_VIRT
.endm
.macro senduart,rd,rx
- str \rd, [\rx, #0]
+ str \rd, [\rx, #UART_DATA]
.endm
.macro busyuart,rd,rx
-1002: ldr \rd, [\rx, #0x18]
- tst \rd, #(1 << 3)
+1002: ldr \rd, [\rx, #UART_FLAG]
+ tst \rd, #UART_FLAG_BUSY
bne 1002b
.endm
.macro waituart,rd,rx
-1001: ldr \rd, [\rx, #0x18]
- tst \rd, #(1 << 3)
+1001: ldr \rd, [\rx, #UART_FLAG]
+ tst \rd, #UART_FLAG_BUSY
bne 1001b
.endm
diff --git a/arch/arm/include/debug/sirf.S b/arch/arm/include/debug/sirf.S
index dbf250cf18e6..630f231f2f37 100644
--- a/arch/arm/include/debug/sirf.S
+++ b/arch/arm/include/debug/sirf.S
@@ -6,37 +6,33 @@
* Licensed under GPLv2 or later.
*/
-#if defined(CONFIG_DEBUG_SIRFPRIMA2_UART1)
-#define SIRFSOC_UART1_PA_BASE 0xb0060000
-#elif defined(CONFIG_DEBUG_SIRFMARCO_UART1)
-#define SIRFSOC_UART1_PA_BASE 0xcc060000
-#else
-#define SIRFSOC_UART1_PA_BASE 0
-#endif
+#define SIRF_LLUART_TXFIFO_STATUS 0x0114
+#define SIRF_LLUART_TXFIFO_DATA 0x0118
-#define SIRFSOC_UART1_VA_BASE 0xFEC60000
+#define SIRF_LLUART_TXFIFO_FULL (1 << 5)
-#define SIRFSOC_UART_TXFIFO_STATUS 0x0114
-#define SIRFSOC_UART_TXFIFO_DATA 0x0118
+#ifdef CONFIG_DEBUG_SIRFATLAS7_UART0
+#define SIRF_LLUART_TXFIFO_EMPTY (1 << 8)
+#else
+#define SIRF_LLUART_TXFIFO_EMPTY (1 << 6)
+#endif
-#define SIRFSOC_UART1_TXFIFO_FULL (1 << 5)
-#define SIRFSOC_UART1_TXFIFO_EMPTY (1 << 6)
.macro addruart, rp, rv, tmp
- ldr \rp, =SIRFSOC_UART1_PA_BASE @ physical
- ldr \rv, =SIRFSOC_UART1_VA_BASE @ virtual
+ ldr \rp, =CONFIG_DEBUG_UART_PHYS @ physical
+ ldr \rv, =CONFIG_DEBUG_UART_VIRT @ virtual
.endm
.macro senduart,rd,rx
- str \rd, [\rx, #SIRFSOC_UART_TXFIFO_DATA]
+ str \rd, [\rx, #SIRF_LLUART_TXFIFO_DATA]
.endm
.macro busyuart,rd,rx
.endm
.macro waituart,rd,rx
-1001: ldr \rd, [\rx, #SIRFSOC_UART_TXFIFO_STATUS]
- tst \rd, #SIRFSOC_UART1_TXFIFO_EMPTY
+1001: ldr \rd, [\rx, #SIRF_LLUART_TXFIFO_STATUS]
+ tst \rd, #SIRF_LLUART_TXFIFO_EMPTY
beq 1001b
.endm
diff --git a/arch/arm/include/uapi/asm/kvm.h b/arch/arm/include/uapi/asm/kvm.h
index 09ee408c1a67..0db25bc32864 100644
--- a/arch/arm/include/uapi/asm/kvm.h
+++ b/arch/arm/include/uapi/asm/kvm.h
@@ -175,6 +175,8 @@ struct kvm_arch_memory_slot {
#define KVM_DEV_ARM_VGIC_OFFSET_SHIFT 0
#define KVM_DEV_ARM_VGIC_OFFSET_MASK (0xffffffffULL << KVM_DEV_ARM_VGIC_OFFSET_SHIFT)
#define KVM_DEV_ARM_VGIC_GRP_NR_IRQS 3
+#define KVM_DEV_ARM_VGIC_GRP_CTRL 4
+#define KVM_DEV_ARM_VGIC_CTRL_INIT 0
/* KVM_IRQ_LINE irq field index values */
#define KVM_ARM_IRQ_TYPE_SHIFT 24
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index fb2b71ebe3f2..902397dd1000 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -51,20 +51,8 @@ obj-$(CONFIG_DYNAMIC_FTRACE) += ftrace.o insn.o
obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o insn.o
obj-$(CONFIG_JUMP_LABEL) += jump_label.o insn.o patch.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
-obj-$(CONFIG_UPROBES) += probes.o probes-arm.o uprobes.o uprobes-arm.o
-obj-$(CONFIG_KPROBES) += probes.o kprobes.o kprobes-common.o patch.o
-ifdef CONFIG_THUMB2_KERNEL
-obj-$(CONFIG_KPROBES) += kprobes-thumb.o probes-thumb.o
-else
-obj-$(CONFIG_KPROBES) += kprobes-arm.o probes-arm.o
-endif
-obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o
-test-kprobes-objs := kprobes-test.o
-ifdef CONFIG_THUMB2_KERNEL
-test-kprobes-objs += kprobes-test-thumb.o
-else
-test-kprobes-objs += kprobes-test-arm.o
-endif
+# Main staffs in KPROBES are in arch/arm/probes/ .
+obj-$(CONFIG_KPROBES) += patch.o insn.o
obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
obj-$(CONFIG_ARM_THUMBEE) += thumbee.o
obj-$(CONFIG_KGDB) += kgdb.o patch.o
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index a4effd6d8f2f..ab19b7c03423 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -422,17 +422,16 @@ static int pcibios_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
static int pcibios_init_resources(int busnr, struct pci_sys_data *sys)
{
int ret;
- struct pci_host_bridge_window *window;
+ struct resource_entry *window;
if (list_empty(&sys->resources)) {
pci_add_resource_offset(&sys->resources,
&iomem_resource, sys->mem_offset);
}
- list_for_each_entry(window, &sys->resources, list) {
+ resource_list_for_each_entry(window, &sys->resources)
if (resource_type(window->res) == IORESOURCE_IO)
return 0;
- }
sys->io_res.start = (busnr * SZ_64K) ? : pcibios_min_io;
sys->io_res.end = (busnr + 1) * SZ_64K - 1;
@@ -463,9 +462,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
if (!sys)
panic("PCI: unable to allocate sys data!");
-#ifdef CONFIG_PCI_DOMAINS
- sys->domain = hw->domain;
-#endif
#ifdef CONFIG_PCI_MSI
sys->msi_ctrl = hw->msi_ctrl;
#endif
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 2f5555d307b3..672b21942fff 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -31,6 +31,7 @@
#include "entry-header.S"
#include <asm/entry-macro-multi.S>
+#include <asm/probes.h>
/*
* Interrupt handling.
@@ -249,7 +250,7 @@ __und_svc:
@ If a kprobe is about to simulate a "stmdb sp..." instruction,
@ it obviously needs free stack space which then will belong to
@ the saved context.
- svc_entry 64
+ svc_entry MAX_STACK_SIZE
#else
svc_entry
#endif
diff --git a/arch/arm/kernel/entry-header.S b/arch/arm/kernel/entry-header.S
index 4176df721bf0..1a0045abead7 100644
--- a/arch/arm/kernel/entry-header.S
+++ b/arch/arm/kernel/entry-header.S
@@ -253,21 +253,22 @@
.endm
.macro restore_user_regs, fast = 0, offset = 0
- ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr
- ldr lr, [sp, #\offset + S_PC]! @ get pc
+ mov r2, sp
+ ldr r1, [r2, #\offset + S_PSR] @ get calling cpsr
+ ldr lr, [r2, #\offset + S_PC]! @ get pc
msr spsr_cxsf, r1 @ save in spsr_svc
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_32v6K)
@ We must avoid clrex due to Cortex-A15 erratum #830321
- strex r1, r2, [sp] @ clear the exclusive monitor
+ strex r1, r2, [r2] @ clear the exclusive monitor
#endif
.if \fast
- ldmdb sp, {r1 - lr}^ @ get calling r1 - lr
+ ldmdb r2, {r1 - lr}^ @ get calling r1 - lr
.else
- ldmdb sp, {r0 - lr}^ @ get calling r0 - lr
+ ldmdb r2, {r0 - lr}^ @ get calling r0 - lr
.endif
mov r0, r0 @ ARMv5T and earlier require a nop
@ after ldm {}^
- add sp, sp, #S_FRAME_SIZE - S_PC
+ add sp, sp, #\offset + S_FRAME_SIZE
movs pc, lr @ return & move spsr_svc into cpsr
.endm
diff --git a/arch/arm/kernel/entry-v7m.S b/arch/arm/kernel/entry-v7m.S
index 2260f1855820..8944f4991c3c 100644
--- a/arch/arm/kernel/entry-v7m.S
+++ b/arch/arm/kernel/entry-v7m.S
@@ -22,10 +22,12 @@
__invalid_entry:
v7m_exception_entry
+#ifdef CONFIG_PRINTK
adr r0, strerr
mrs r1, ipsr
mov r2, lr
bl printk
+#endif
mov r0, sp
bl show_regs
1: b 1b
diff --git a/arch/arm/kernel/ftrace.c b/arch/arm/kernel/ftrace.c
index b8c75e45a950..709ee1d6d4df 100644
--- a/arch/arm/kernel/ftrace.c
+++ b/arch/arm/kernel/ftrace.c
@@ -20,8 +20,7 @@
#include <asm/cacheflush.h>
#include <asm/opcodes.h>
#include <asm/ftrace.h>
-
-#include "insn.h"
+#include <asm/insn.h>
#ifdef CONFIG_THUMB2_KERNEL
#define NOP 0xf85deb04 /* pop.w {lr} */
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 664eee8c4a26..01963273c07a 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -346,6 +346,12 @@ __turn_mmu_on_loc:
#if defined(CONFIG_SMP)
.text
+ENTRY(secondary_startup_arm)
+ .arm
+ THUMB( adr r9, BSYM(1f) ) @ Kernel is entered in ARM.
+ THUMB( bx r9 ) @ If this is a Thumb-2 kernel,
+ THUMB( .thumb ) @ switch to Thumb now.
+ THUMB(1: )
ENTRY(secondary_startup)
/*
* Common entry point for secondary CPUs.
@@ -385,6 +391,7 @@ ENTRY(secondary_startup)
THUMB( add r12, r10, #PROCINFO_INITFUNC )
THUMB( ret r12 )
ENDPROC(secondary_startup)
+ENDPROC(secondary_startup_arm)
/*
* r6 = &secondary_data
@@ -586,7 +593,7 @@ __fixup_pv_table:
add r5, r5, r3 @ adjust table end address
add r6, r6, r3 @ adjust __pv_phys_pfn_offset address
add r7, r7, r3 @ adjust __pv_offset address
- mov r0, r8, lsr #12 @ convert to PFN
+ mov r0, r8, lsr #PAGE_SHIFT @ convert to PFN
str r0, [r6] @ save computed PHYS_OFFSET to __pv_phys_pfn_offset
strcc ip, [r7, #HIGH_OFFSET] @ save to __pv_offset high bits
mov r6, r3, lsr #24 @ constant for add/sub instructions
diff --git a/arch/arm/kernel/irq.c b/arch/arm/kernel/irq.c
index ad857bada96c..350f188c92d2 100644
--- a/arch/arm/kernel/irq.c
+++ b/arch/arm/kernel/irq.c
@@ -109,7 +109,8 @@ void __init init_IRQ(void)
if (IS_ENABLED(CONFIG_OF) && IS_ENABLED(CONFIG_CACHE_L2X0) &&
(machine_desc->l2c_aux_mask || machine_desc->l2c_aux_val)) {
- outer_cache.write_sec = machine_desc->l2c_write_sec;
+ if (!outer_cache.write_sec)
+ outer_cache.write_sec = machine_desc->l2c_write_sec;
ret = l2x0_of_init(machine_desc->l2c_aux_val,
machine_desc->l2c_aux_mask);
if (ret)
diff --git a/arch/arm/kernel/jump_label.c b/arch/arm/kernel/jump_label.c
index afeeb9ea6f43..e39cbf488cfe 100644
--- a/arch/arm/kernel/jump_label.c
+++ b/arch/arm/kernel/jump_label.c
@@ -1,8 +1,7 @@
#include <linux/kernel.h>
#include <linux/jump_label.h>
-
-#include "insn.h"
-#include "patch.h"
+#include <asm/patch.h>
+#include <asm/insn.h>
#ifdef HAVE_JUMP_LABEL
diff --git a/arch/arm/kernel/kgdb.c b/arch/arm/kernel/kgdb.c
index 07db2f8a1b45..a6ad93c9bce3 100644
--- a/arch/arm/kernel/kgdb.c
+++ b/arch/arm/kernel/kgdb.c
@@ -14,10 +14,9 @@
#include <linux/kgdb.h>
#include <linux/uaccess.h>
+#include <asm/patch.h>
#include <asm/traps.h>
-#include "patch.h"
-
struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] =
{
{ "r0", 4, offsetof(struct pt_regs, ARM_r0)},
diff --git a/arch/arm/kernel/module.c b/arch/arm/kernel/module.c
index bea7db9e5b80..2e11961f65ae 100644
--- a/arch/arm/kernel/module.c
+++ b/arch/arm/kernel/module.c
@@ -41,7 +41,7 @@
void *module_alloc(unsigned long size)
{
return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END,
- GFP_KERNEL, PAGE_KERNEL_EXEC, NUMA_NO_NODE,
+ GFP_KERNEL, PAGE_KERNEL_EXEC, 0, NUMA_NO_NODE,
__builtin_return_address(0));
}
#endif
diff --git a/arch/arm/kernel/patch.c b/arch/arm/kernel/patch.c
index 5038960e3c55..69bda1a5707e 100644
--- a/arch/arm/kernel/patch.c
+++ b/arch/arm/kernel/patch.c
@@ -8,8 +8,7 @@
#include <asm/fixmap.h>
#include <asm/smp_plat.h>
#include <asm/opcodes.h>
-
-#include "patch.h"
+#include <asm/patch.h>
struct patch {
void *addr;
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index f7c65adaa428..557e128e4df0 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -116,8 +116,14 @@ int armpmu_event_set_period(struct perf_event *event)
ret = 1;
}
- if (left > (s64)armpmu->max_period)
- left = armpmu->max_period;
+ /*
+ * Limit the maximum period to prevent the counter value
+ * from overtaking the one we are about to program. In
+ * effect we are reducing max_period to account for
+ * interrupt latency (and we are being very conservative).
+ */
+ if (left > (armpmu->max_period >> 1))
+ left = armpmu->max_period >> 1;
local64_set(&hwc->prev_count, (u64)-left);
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 715ae19bc7c8..e55408e96559 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -657,10 +657,13 @@ int __init arm_add_memory(u64 start, u64 size)
/*
* Ensure that start/size are aligned to a page boundary.
- * Size is appropriately rounded down, start is rounded up.
+ * Size is rounded down, start is rounded up.
*/
- size -= start & ~PAGE_MASK;
aligned_start = PAGE_ALIGN(start);
+ if (aligned_start > start + size)
+ size = 0;
+ else
+ size -= aligned_start - start;
#ifndef CONFIG_ARCH_PHYS_ADDR_T_64BIT
if (aligned_start > ULONG_MAX) {
diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c
index 8aa6f1b87c9e..023ac905e4c3 100644
--- a/arch/arm/kernel/signal.c
+++ b/arch/arm/kernel/signal.c
@@ -191,7 +191,7 @@ asmlinkage int sys_sigreturn(struct pt_regs *regs)
struct sigframe __user *frame;
/* Always make any pending restarted system calls return -EINTR */
- current_thread_info()->restart_block.fn = do_no_restart_syscall;
+ current->restart_block.fn = do_no_restart_syscall;
/*
* Since we stacked the signal on a 64-bit boundary,
@@ -221,7 +221,7 @@ asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
struct rt_sigframe __user *frame;
/* Always make any pending restarted system calls return -EINTR */
- current_thread_info()->restart_block.fn = do_no_restart_syscall;
+ current->restart_block.fn = do_no_restart_syscall;
/*
* Since we stacked the signal on a 64-bit boundary,
diff --git a/arch/arm/kernel/suspend.c b/arch/arm/kernel/suspend.c
index 2835d35234ca..9a2f882a0a2d 100644
--- a/arch/arm/kernel/suspend.c
+++ b/arch/arm/kernel/suspend.c
@@ -14,10 +14,6 @@ extern int __cpu_suspend(unsigned long, int (*)(unsigned long), u32 cpuid);
extern void cpu_resume_mmu(void);
#ifdef CONFIG_MMU
-/*
- * Hide the first two arguments to __cpu_suspend - these are an implementation
- * detail which platform code shouldn't have to know about.
- */
int cpu_suspend(unsigned long arg, int (*fn)(unsigned long))
{
struct mm_struct *mm = current->active_mm;
diff --git a/arch/arm/kvm/Kconfig b/arch/arm/kvm/Kconfig
index 466bd299b1a8..338ace78ed18 100644
--- a/arch/arm/kvm/Kconfig
+++ b/arch/arm/kvm/Kconfig
@@ -21,8 +21,11 @@ config KVM
select PREEMPT_NOTIFIERS
select ANON_INODES
select HAVE_KVM_CPU_RELAX_INTERCEPT
+ select HAVE_KVM_ARCH_TLB_FLUSH_ALL
select KVM_MMIO
select KVM_ARM_HOST
+ select KVM_GENERIC_DIRTYLOG_READ_PROTECT
+ select SRCU
depends on ARM_VIRT_EXT && ARM_LPAE
---help---
Support hosting virtualized guest machines. You will also
diff --git a/arch/arm/kvm/Makefile b/arch/arm/kvm/Makefile
index f7057ed045b6..443b8bea43e9 100644
--- a/arch/arm/kvm/Makefile
+++ b/arch/arm/kvm/Makefile
@@ -22,4 +22,5 @@ obj-y += arm.o handle_exit.o guest.o mmu.o emulate.o reset.o
obj-y += coproc.o coproc_a15.o coproc_a7.o mmio.o psci.o perf.o
obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic.o
obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2.o
+obj-$(CONFIG_KVM_ARM_VGIC) += $(KVM)/arm/vgic-v2-emul.o
obj-$(CONFIG_KVM_ARM_TIMER) += $(KVM)/arm/arch_timer.o
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 2d6d91001062..07e7eb1d7ab6 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -132,6 +132,9 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type)
/* Mark the initial VMID generation invalid */
kvm->arch.vmid_gen = 0;
+ /* The maximum number of VCPUs is limited by the host's GIC model */
+ kvm->arch.max_vcpus = kvm_vgic_get_max_vcpus();
+
return ret;
out_free_stage2_pgd:
kvm_free_stage2_pgd(kvm);
@@ -218,6 +221,11 @@ struct kvm_vcpu *kvm_arch_vcpu_create(struct kvm *kvm, unsigned int id)
goto out;
}
+ if (id >= kvm->arch.max_vcpus) {
+ err = -EINVAL;
+ goto out;
+ }
+
vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL);
if (!vcpu) {
err = -ENOMEM;
@@ -241,9 +249,8 @@ out:
return ERR_PTR(err);
}
-int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
+void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
{
- return 0;
}
void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
@@ -281,15 +288,6 @@ void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
vcpu->cpu = cpu;
vcpu->arch.host_cpu_context = this_cpu_ptr(kvm_host_cpu_state);
- /*
- * Check whether this vcpu requires the cache to be flushed on
- * this physical CPU. This is a consequence of doing dcache
- * operations by set/way on this vcpu. We do it here to be in
- * a non-preemptible section.
- */
- if (cpumask_test_and_clear_cpu(cpu, &vcpu->arch.require_dcache_flush))
- flush_cache_all(); /* We'd really want v7_flush_dcache_all() */
-
kvm_arm_set_running_vcpu(vcpu);
}
@@ -541,7 +539,6 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *run)
ret = kvm_call_hyp(__kvm_vcpu_run, vcpu);
vcpu->mode = OUTSIDE_GUEST_MODE;
- vcpu->arch.last_pcpu = smp_processor_id();
kvm_guest_exit();
trace_kvm_exit(*vcpu_pc(vcpu));
/*
@@ -787,9 +784,39 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
}
}
+/**
+ * kvm_vm_ioctl_get_dirty_log - get and clear the log of dirty pages in a slot
+ * @kvm: kvm instance
+ * @log: slot id and address to which we copy the log
+ *
+ * Steps 1-4 below provide general overview of dirty page logging. See
+ * kvm_get_dirty_log_protect() function description for additional details.
+ *
+ * We call kvm_get_dirty_log_protect() to handle steps 1-3, upon return we
+ * always flush the TLB (step 4) even if previous step failed and the dirty
+ * bitmap may be corrupt. Regardless of previous outcome the KVM logging API
+ * does not preclude user space subsequent dirty log read. Flushing TLB ensures
+ * writes will be marked dirty for next log read.
+ *
+ * 1. Take a snapshot of the bit and clear it if needed.
+ * 2. Write protect the corresponding page.
+ * 3. Copy the snapshot to the userspace.
+ * 4. Flush TLB's if needed.
+ */
int kvm_vm_ioctl_get_dirty_log(struct kvm *kvm, struct kvm_dirty_log *log)
{
- return -EINVAL;
+ bool is_dirty = false;
+ int r;
+
+ mutex_lock(&kvm->slots_lock);
+
+ r = kvm_get_dirty_log_protect(kvm, log, &is_dirty);
+
+ if (is_dirty)
+ kvm_flush_remote_tlbs(kvm);
+
+ mutex_unlock(&kvm->slots_lock);
+ return r;
}
static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
@@ -821,7 +848,7 @@ long kvm_arch_vm_ioctl(struct file *filp,
switch (ioctl) {
case KVM_CREATE_IRQCHIP: {
if (vgic_present)
- return kvm_vgic_create(kvm);
+ return kvm_vgic_create(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);
else
return -ENXIO;
}
@@ -1045,6 +1072,19 @@ static void check_kvm_target_cpu(void *ret)
*(int *)ret = kvm_target_cpu();
}
+struct kvm_vcpu *kvm_mpidr_to_vcpu(struct kvm *kvm, unsigned long mpidr)
+{
+ struct kvm_vcpu *vcpu;
+ int i;
+
+ mpidr &= MPIDR_HWID_BITMASK;
+ kvm_for_each_vcpu(i, vcpu, kvm) {
+ if (mpidr == kvm_vcpu_get_mpidr_aff(vcpu))
+ return vcpu;
+ }
+ return NULL;
+}
+
/**
* Initialize Hyp-mode and memory mappings on all CPUs.
*/
diff --git a/arch/arm/kvm/coproc.c b/arch/arm/kvm/coproc.c
index 7928dbdf2102..f3d88dc388bc 100644
--- a/arch/arm/kvm/coproc.c
+++ b/arch/arm/kvm/coproc.c
@@ -189,82 +189,40 @@ static bool access_l2ectlr(struct kvm_vcpu *vcpu,
return true;
}
-/* See note at ARM ARM B1.14.4 */
+/*
+ * See note at ARMv7 ARM B1.14.4 (TL;DR: S/W ops are not easily virtualized).
+ */
static bool access_dcsw(struct kvm_vcpu *vcpu,
const struct coproc_params *p,
const struct coproc_reg *r)
{
- unsigned long val;
- int cpu;
-
if (!p->is_write)
return read_from_write_only(vcpu, p);
- cpu = get_cpu();
-
- cpumask_setall(&vcpu->arch.require_dcache_flush);
- cpumask_clear_cpu(cpu, &vcpu->arch.require_dcache_flush);
-
- /* If we were already preempted, take the long way around */
- if (cpu != vcpu->arch.last_pcpu) {
- flush_cache_all();
- goto done;
- }
-
- val = *vcpu_reg(vcpu, p->Rt1);
-
- switch (p->CRm) {
- case 6: /* Upgrade DCISW to DCCISW, as per HCR.SWIO */
- case 14: /* DCCISW */
- asm volatile("mcr p15, 0, %0, c7, c14, 2" : : "r" (val));
- break;
-
- case 10: /* DCCSW */
- asm volatile("mcr p15, 0, %0, c7, c10, 2" : : "r" (val));
- break;
- }
-
-done:
- put_cpu();
-
+ kvm_set_way_flush(vcpu);
return true;
}
/*
* Generic accessor for VM registers. Only called as long as HCR_TVM
- * is set.
+ * is set. If the guest enables the MMU, we stop trapping the VM
+ * sys_regs and leave it in complete control of the caches.
+ *
+ * Used by the cpu-specific code.
*/
-static bool access_vm_reg(struct kvm_vcpu *vcpu,
- const struct coproc_params *p,
- const struct coproc_reg *r)
+bool access_vm_reg(struct kvm_vcpu *vcpu,
+ const struct coproc_params *p,
+ const struct coproc_reg *r)
{
+ bool was_enabled = vcpu_has_cache_enabled(vcpu);
+
BUG_ON(!p->is_write);
vcpu->arch.cp15[r->reg] = *vcpu_reg(vcpu, p->Rt1);
if (p->is_64bit)
vcpu->arch.cp15[r->reg + 1] = *vcpu_reg(vcpu, p->Rt2);
- return true;
-}
-
-/*
- * SCTLR accessor. Only called as long as HCR_TVM is set. If the
- * guest enables the MMU, we stop trapping the VM sys_regs and leave
- * it in complete control of the caches.
- *
- * Used by the cpu-specific code.
- */
-bool access_sctlr(struct kvm_vcpu *vcpu,
- const struct coproc_params *p,
- const struct coproc_reg *r)
-{
- access_vm_reg(vcpu, p, r);
-
- if (vcpu_has_cache_enabled(vcpu)) { /* MMU+Caches enabled? */
- vcpu->arch.hcr &= ~HCR_TVM;
- stage2_flush_vm(vcpu->kvm);
- }
-
+ kvm_toggle_cache(vcpu, was_enabled);
return true;
}
diff --git a/arch/arm/kvm/coproc.h b/arch/arm/kvm/coproc.h
index 1a44bbe39643..88d24a3a9778 100644
--- a/arch/arm/kvm/coproc.h
+++ b/arch/arm/kvm/coproc.h
@@ -153,8 +153,8 @@ static inline int cmp_reg(const struct coproc_reg *i1,
#define is64 .is_64 = true
#define is32 .is_64 = false
-bool access_sctlr(struct kvm_vcpu *vcpu,
- const struct coproc_params *p,
- const struct coproc_reg *r);
+bool access_vm_reg(struct kvm_vcpu *vcpu,
+ const struct coproc_params *p,
+ const struct coproc_reg *r);
#endif /* __ARM_KVM_COPROC_LOCAL_H__ */
diff --git a/arch/arm/kvm/coproc_a15.c b/arch/arm/kvm/coproc_a15.c
index e6f4ae48bda9..a7136757d373 100644
--- a/arch/arm/kvm/coproc_a15.c
+++ b/arch/arm/kvm/coproc_a15.c
@@ -34,7 +34,7 @@
static const struct coproc_reg a15_regs[] = {
/* SCTLR: swapped by interrupt.S. */
{ CRn( 1), CRm( 0), Op1( 0), Op2( 0), is32,
- access_sctlr, reset_val, c1_SCTLR, 0x00C50078 },
+ access_vm_reg, reset_val, c1_SCTLR, 0x00C50078 },
};
static struct kvm_coproc_target_table a15_target_table = {
diff --git a/arch/arm/kvm/coproc_a7.c b/arch/arm/kvm/coproc_a7.c
index 17fc7cd479d3..b19e46d1b2c0 100644
--- a/arch/arm/kvm/coproc_a7.c
+++ b/arch/arm/kvm/coproc_a7.c
@@ -37,7 +37,7 @@
static const struct coproc_reg a7_regs[] = {
/* SCTLR: swapped by interrupt.S. */
{ CRn( 1), CRm( 0), Op1( 0), Op2( 0), is32,
- access_sctlr, reset_val, c1_SCTLR, 0x00C50878 },
+ access_vm_reg, reset_val, c1_SCTLR, 0x00C50878 },
};
static struct kvm_coproc_target_table a7_target_table = {
diff --git a/arch/arm/kvm/handle_exit.c b/arch/arm/kvm/handle_exit.c
index a96a8043277c..95f12b2ccdcb 100644
--- a/arch/arm/kvm/handle_exit.c
+++ b/arch/arm/kvm/handle_exit.c
@@ -87,11 +87,13 @@ static int handle_dabt_hyp(struct kvm_vcpu *vcpu, struct kvm_run *run)
*/
static int kvm_handle_wfx(struct kvm_vcpu *vcpu, struct kvm_run *run)
{
- trace_kvm_wfi(*vcpu_pc(vcpu));
- if (kvm_vcpu_get_hsr(vcpu) & HSR_WFI_IS_WFE)
+ if (kvm_vcpu_get_hsr(vcpu) & HSR_WFI_IS_WFE) {
+ trace_kvm_wfx(*vcpu_pc(vcpu), true);
kvm_vcpu_on_spin(vcpu);
- else
+ } else {
+ trace_kvm_wfx(*vcpu_pc(vcpu), false);
kvm_vcpu_block(vcpu);
+ }
kvm_skip_instr(vcpu, kvm_vcpu_trap_il_is32bit(vcpu));
diff --git a/arch/arm/kvm/interrupts.S b/arch/arm/kvm/interrupts.S
index 01dcb0e752d9..79caf79b304a 100644
--- a/arch/arm/kvm/interrupts.S
+++ b/arch/arm/kvm/interrupts.S
@@ -66,6 +66,17 @@ ENTRY(__kvm_tlb_flush_vmid_ipa)
bx lr
ENDPROC(__kvm_tlb_flush_vmid_ipa)
+/**
+ * void __kvm_tlb_flush_vmid(struct kvm *kvm) - Flush per-VMID TLBs
+ *
+ * Reuses __kvm_tlb_flush_vmid_ipa() for ARMv7, without passing address
+ * parameter
+ */
+
+ENTRY(__kvm_tlb_flush_vmid)
+ b __kvm_tlb_flush_vmid_ipa
+ENDPROC(__kvm_tlb_flush_vmid)
+
/********************************************************************
* Flush TLBs and instruction caches of all CPUs inside the inner-shareable
* domain, for all VMIDs
diff --git a/arch/arm/kvm/mmu.c b/arch/arm/kvm/mmu.c
index 1dc9778a00af..3e6859bc3e11 100644
--- a/arch/arm/kvm/mmu.c
+++ b/arch/arm/kvm/mmu.c
@@ -45,6 +45,26 @@ static phys_addr_t hyp_idmap_vector;
#define hyp_pgd_order get_order(PTRS_PER_PGD * sizeof(pgd_t))
#define kvm_pmd_huge(_x) (pmd_huge(_x) || pmd_trans_huge(_x))
+#define kvm_pud_huge(_x) pud_huge(_x)
+
+#define KVM_S2PTE_FLAG_IS_IOMAP (1UL << 0)
+#define KVM_S2_FLAG_LOGGING_ACTIVE (1UL << 1)
+
+static bool memslot_is_logging(struct kvm_memory_slot *memslot)
+{
+ return memslot->dirty_bitmap && !(memslot->flags & KVM_MEM_READONLY);
+}
+
+/**
+ * kvm_flush_remote_tlbs() - flush all VM TLB entries for v7/8
+ * @kvm: pointer to kvm structure.
+ *
+ * Interface to HYP function to flush all VM TLB entries
+ */
+void kvm_flush_remote_tlbs(struct kvm *kvm)
+{
+ kvm_call_hyp(__kvm_tlb_flush_vmid, kvm);
+}
static void kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
{
@@ -58,6 +78,45 @@ static void kvm_tlb_flush_vmid_ipa(struct kvm *kvm, phys_addr_t ipa)
kvm_call_hyp(__kvm_tlb_flush_vmid_ipa, kvm, ipa);
}
+/*
+ * D-Cache management functions. They take the page table entries by
+ * value, as they are flushing the cache using the kernel mapping (or
+ * kmap on 32bit).
+ */
+static void kvm_flush_dcache_pte(pte_t pte)
+{
+ __kvm_flush_dcache_pte(pte);
+}
+
+static void kvm_flush_dcache_pmd(pmd_t pmd)
+{
+ __kvm_flush_dcache_pmd(pmd);
+}
+
+static void kvm_flush_dcache_pud(pud_t pud)
+{
+ __kvm_flush_dcache_pud(pud);
+}
+
+/**
+ * stage2_dissolve_pmd() - clear and flush huge PMD entry
+ * @kvm: pointer to kvm structure.
+ * @addr: IPA
+ * @pmd: pmd pointer for IPA
+ *
+ * Function clears a PMD entry, flushes addr 1st and 2nd stage TLBs. Marks all
+ * pages in the range dirty.
+ */
+static void stage2_dissolve_pmd(struct kvm *kvm, phys_addr_t addr, pmd_t *pmd)
+{
+ if (!kvm_pmd_huge(*pmd))
+ return;
+
+ pmd_clear(pmd);
+ kvm_tlb_flush_vmid_ipa(kvm, addr);
+ put_page(virt_to_page(pmd));
+}
+
static int mmu_topup_memory_cache(struct kvm_mmu_memory_cache *cache,
int min, int max)
{
@@ -119,6 +178,26 @@ static void clear_pmd_entry(struct kvm *kvm, pmd_t *pmd, phys_addr_t addr)
put_page(virt_to_page(pmd));
}
+/*
+ * Unmapping vs dcache management:
+ *
+ * If a guest maps certain memory pages as uncached, all writes will
+ * bypass the data cache and go directly to RAM. However, the CPUs
+ * can still speculate reads (not writes) and fill cache lines with
+ * data.
+ *
+ * Those cache lines will be *clean* cache lines though, so a
+ * clean+invalidate operation is equivalent to an invalidate
+ * operation, because no cache lines are marked dirty.
+ *
+ * Those clean cache lines could be filled prior to an uncached write
+ * by the guest, and the cache coherent IO subsystem would therefore
+ * end up writing old data to disk.
+ *
+ * This is why right after unmapping a page/section and invalidating
+ * the corresponding TLBs, we call kvm_flush_dcache_p*() to make sure
+ * the IO subsystem will never hit in the cache.
+ */
static void unmap_ptes(struct kvm *kvm, pmd_t *pmd,
phys_addr_t addr, phys_addr_t end)
{
@@ -128,9 +207,16 @@ static void unmap_ptes(struct kvm *kvm, pmd_t *pmd,
start_pte = pte = pte_offset_kernel(pmd, addr);
do {
if (!pte_none(*pte)) {
+ pte_t old_pte = *pte;
+
kvm_set_pte(pte, __pte(0));
- put_page(virt_to_page(pte));
kvm_tlb_flush_vmid_ipa(kvm, addr);
+
+ /* No need to invalidate the cache for device mappings */
+ if ((pte_val(old_pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE)
+ kvm_flush_dcache_pte(old_pte);
+
+ put_page(virt_to_page(pte));
}
} while (pte++, addr += PAGE_SIZE, addr != end);
@@ -149,8 +235,13 @@ static void unmap_pmds(struct kvm *kvm, pud_t *pud,
next = kvm_pmd_addr_end(addr, end);
if (!pmd_none(*pmd)) {
if (kvm_pmd_huge(*pmd)) {
+ pmd_t old_pmd = *pmd;
+
pmd_clear(pmd);
kvm_tlb_flush_vmid_ipa(kvm, addr);
+
+ kvm_flush_dcache_pmd(old_pmd);
+
put_page(virt_to_page(pmd));
} else {
unmap_ptes(kvm, pmd, addr, next);
@@ -173,8 +264,13 @@ static void unmap_puds(struct kvm *kvm, pgd_t *pgd,
next = kvm_pud_addr_end(addr, end);
if (!pud_none(*pud)) {
if (pud_huge(*pud)) {
+ pud_t old_pud = *pud;
+
pud_clear(pud);
kvm_tlb_flush_vmid_ipa(kvm, addr);
+
+ kvm_flush_dcache_pud(old_pud);
+
put_page(virt_to_page(pud));
} else {
unmap_pmds(kvm, pud, addr, next);
@@ -209,10 +305,9 @@ static void stage2_flush_ptes(struct kvm *kvm, pmd_t *pmd,
pte = pte_offset_kernel(pmd, addr);
do {
- if (!pte_none(*pte)) {
- hva_t hva = gfn_to_hva(kvm, addr >> PAGE_SHIFT);
- kvm_flush_dcache_to_poc((void*)hva, PAGE_SIZE);
- }
+ if (!pte_none(*pte) &&
+ (pte_val(*pte) & PAGE_S2_DEVICE) != PAGE_S2_DEVICE)
+ kvm_flush_dcache_pte(*pte);
} while (pte++, addr += PAGE_SIZE, addr != end);
}
@@ -226,12 +321,10 @@ static void stage2_flush_pmds(struct kvm *kvm, pud_t *pud,
do {
next = kvm_pmd_addr_end(addr, end);
if (!pmd_none(*pmd)) {
- if (kvm_pmd_huge(*pmd)) {
- hva_t hva = gfn_to_hva(kvm, addr >> PAGE_SHIFT);
- kvm_flush_dcache_to_poc((void*)hva, PMD_SIZE);
- } else {
+ if (kvm_pmd_huge(*pmd))
+ kvm_flush_dcache_pmd(*pmd);
+ else
stage2_flush_ptes(kvm, pmd, addr, next);
- }
}
} while (pmd++, addr = next, addr != end);
}
@@ -246,12 +339,10 @@ static void stage2_flush_puds(struct kvm *kvm, pgd_t *pgd,
do {
next = kvm_pud_addr_end(addr, end);
if (!pud_none(*pud)) {
- if (pud_huge(*pud)) {
- hva_t hva = gfn_to_hva(kvm, addr >> PAGE_SHIFT);
- kvm_flush_dcache_to_poc((void*)hva, PUD_SIZE);
- } else {
+ if (pud_huge(*pud))
+ kvm_flush_dcache_pud(*pud);
+ else
stage2_flush_pmds(kvm, pud, addr, next);
- }
}
} while (pud++, addr = next, addr != end);
}
@@ -278,7 +369,7 @@ static void stage2_flush_memslot(struct kvm *kvm,
* Go through the stage 2 page tables and invalidate any cache lines
* backing memory already mapped to the VM.
*/
-void stage2_flush_vm(struct kvm *kvm)
+static void stage2_flush_vm(struct kvm *kvm)
{
struct kvm_memslots *slots;
struct kvm_memory_slot *memslot;
@@ -767,10 +858,15 @@ static int stage2_set_pmd_huge(struct kvm *kvm, struct kvm_mmu_memory_cache
}
static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
- phys_addr_t addr, const pte_t *new_pte, bool iomap)
+ phys_addr_t addr, const pte_t *new_pte,
+ unsigned long flags)
{
pmd_t *pmd;
pte_t *pte, old_pte;
+ bool iomap = flags & KVM_S2PTE_FLAG_IS_IOMAP;
+ bool logging_active = flags & KVM_S2_FLAG_LOGGING_ACTIVE;
+
+ VM_BUG_ON(logging_active && !cache);
/* Create stage-2 page table mapping - Levels 0 and 1 */
pmd = stage2_get_pmd(kvm, cache, addr);
@@ -782,6 +878,13 @@ static int stage2_set_pte(struct kvm *kvm, struct kvm_mmu_memory_cache *cache,
return 0;
}
+ /*
+ * While dirty page logging - dissolve huge PMD, then continue on to
+ * allocate page.
+ */
+ if (logging_active)
+ stage2_dissolve_pmd(kvm, addr, pmd);
+
/* Create stage-2 page mappings - Level 2 */
if (pmd_none(*pmd)) {
if (!cache)
@@ -838,7 +941,8 @@ int kvm_phys_addr_ioremap(struct kvm *kvm, phys_addr_t guest_ipa,
if (ret)
goto out;
spin_lock(&kvm->mmu_lock);
- ret = stage2_set_pte(kvm, &cache, addr, &pte, true);
+ ret = stage2_set_pte(kvm, &cache, addr, &pte,
+ KVM_S2PTE_FLAG_IS_IOMAP);
spin_unlock(&kvm->mmu_lock);
if (ret)
goto out;
@@ -905,6 +1009,171 @@ static bool kvm_is_device_pfn(unsigned long pfn)
return !pfn_valid(pfn);
}
+/**
+ * stage2_wp_ptes - write protect PMD range
+ * @pmd: pointer to pmd entry
+ * @addr: range start address
+ * @end: range end address
+ */
+static void stage2_wp_ptes(pmd_t *pmd, phys_addr_t addr, phys_addr_t end)
+{
+ pte_t *pte;
+
+ pte = pte_offset_kernel(pmd, addr);
+ do {
+ if (!pte_none(*pte)) {
+ if (!kvm_s2pte_readonly(pte))
+ kvm_set_s2pte_readonly(pte);
+ }
+ } while (pte++, addr += PAGE_SIZE, addr != end);
+}
+
+/**
+ * stage2_wp_pmds - write protect PUD range
+ * @pud: pointer to pud entry
+ * @addr: range start address
+ * @end: range end address
+ */
+static void stage2_wp_pmds(pud_t *pud, phys_addr_t addr, phys_addr_t end)
+{
+ pmd_t *pmd;
+ phys_addr_t next;
+
+ pmd = pmd_offset(pud, addr);
+
+ do {
+ next = kvm_pmd_addr_end(addr, end);
+ if (!pmd_none(*pmd)) {
+ if (kvm_pmd_huge(*pmd)) {
+ if (!kvm_s2pmd_readonly(pmd))
+ kvm_set_s2pmd_readonly(pmd);
+ } else {
+ stage2_wp_ptes(pmd, addr, next);
+ }
+ }
+ } while (pmd++, addr = next, addr != end);
+}
+
+/**
+ * stage2_wp_puds - write protect PGD range
+ * @pgd: pointer to pgd entry
+ * @addr: range start address
+ * @end: range end address
+ *
+ * Process PUD entries, for a huge PUD we cause a panic.
+ */
+static void stage2_wp_puds(pgd_t *pgd, phys_addr_t addr, phys_addr_t end)
+{
+ pud_t *pud;
+ phys_addr_t next;
+
+ pud = pud_offset(pgd, addr);
+ do {
+ next = kvm_pud_addr_end(addr, end);
+ if (!pud_none(*pud)) {
+ /* TODO:PUD not supported, revisit later if supported */
+ BUG_ON(kvm_pud_huge(*pud));
+ stage2_wp_pmds(pud, addr, next);
+ }
+ } while (pud++, addr = next, addr != end);
+}
+
+/**
+ * stage2_wp_range() - write protect stage2 memory region range
+ * @kvm: The KVM pointer
+ * @addr: Start address of range
+ * @end: End address of range
+ */
+static void stage2_wp_range(struct kvm *kvm, phys_addr_t addr, phys_addr_t end)
+{
+ pgd_t *pgd;
+ phys_addr_t next;
+
+ pgd = kvm->arch.pgd + pgd_index(addr);
+ do {
+ /*
+ * Release kvm_mmu_lock periodically if the memory region is
+ * large. Otherwise, we may see kernel panics with
+ * CONFIG_DETECT_HUNG_TASK, CONFIG_LOCKUP_DETECTOR,
+ * CONFIG_LOCKDEP. Additionally, holding the lock too long
+ * will also starve other vCPUs.
+ */
+ if (need_resched() || spin_needbreak(&kvm->mmu_lock))
+ cond_resched_lock(&kvm->mmu_lock);
+
+ next = kvm_pgd_addr_end(addr, end);
+ if (pgd_present(*pgd))
+ stage2_wp_puds(pgd, addr, next);
+ } while (pgd++, addr = next, addr != end);
+}
+
+/**
+ * kvm_mmu_wp_memory_region() - write protect stage 2 entries for memory slot
+ * @kvm: The KVM pointer
+ * @slot: The memory slot to write protect
+ *
+ * Called to start logging dirty pages after memory region
+ * KVM_MEM_LOG_DIRTY_PAGES operation is called. After this function returns
+ * all present PMD and PTEs are write protected in the memory region.
+ * Afterwards read of dirty page log can be called.
+ *
+ * Acquires kvm_mmu_lock. Called with kvm->slots_lock mutex acquired,
+ * serializing operations for VM memory regions.
+ */
+void kvm_mmu_wp_memory_region(struct kvm *kvm, int slot)
+{
+ struct kvm_memory_slot *memslot = id_to_memslot(kvm->memslots, slot);
+ phys_addr_t start = memslot->base_gfn << PAGE_SHIFT;
+ phys_addr_t end = (memslot->base_gfn + memslot->npages) << PAGE_SHIFT;
+
+ spin_lock(&kvm->mmu_lock);
+ stage2_wp_range(kvm, start, end);
+ spin_unlock(&kvm->mmu_lock);
+ kvm_flush_remote_tlbs(kvm);
+}
+
+/**
+ * kvm_mmu_write_protect_pt_masked() - write protect dirty pages
+ * @kvm: The KVM pointer
+ * @slot: The memory slot associated with mask
+ * @gfn_offset: The gfn offset in memory slot
+ * @mask: The mask of dirty pages at offset 'gfn_offset' in this memory
+ * slot to be write protected
+ *
+ * Walks bits set in mask write protects the associated pte's. Caller must
+ * acquire kvm_mmu_lock.
+ */
+static void kvm_mmu_write_protect_pt_masked(struct kvm *kvm,
+ struct kvm_memory_slot *slot,
+ gfn_t gfn_offset, unsigned long mask)
+{
+ phys_addr_t base_gfn = slot->base_gfn + gfn_offset;
+ phys_addr_t start = (base_gfn + __ffs(mask)) << PAGE_SHIFT;
+ phys_addr_t end = (base_gfn + __fls(mask) + 1) << PAGE_SHIFT;
+
+ stage2_wp_range(kvm, start, end);
+}
+
+/*
+ * kvm_arch_mmu_enable_log_dirty_pt_masked - enable dirty logging for selected
+ * dirty pages.
+ *
+ * It calls kvm_mmu_write_protect_pt_masked to write protect selected pages to
+ * enable dirty logging for them.
+ */
+void kvm_arch_mmu_enable_log_dirty_pt_masked(struct kvm *kvm,
+ struct kvm_memory_slot *slot,
+ gfn_t gfn_offset, unsigned long mask)
+{
+ kvm_mmu_write_protect_pt_masked(kvm, slot, gfn_offset, mask);
+}
+
+static void coherent_cache_guest_page(struct kvm_vcpu *vcpu, pfn_t pfn,
+ unsigned long size, bool uncached)
+{
+ __coherent_cache_guest_page(vcpu, pfn, size, uncached);
+}
+
static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
struct kvm_memory_slot *memslot, unsigned long hva,
unsigned long fault_status)
@@ -919,6 +1188,8 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
pfn_t pfn;
pgprot_t mem_type = PAGE_S2;
bool fault_ipa_uncached;
+ bool logging_active = memslot_is_logging(memslot);
+ unsigned long flags = 0;
write_fault = kvm_is_write_fault(vcpu);
if (fault_status == FSC_PERM && !write_fault) {
@@ -935,7 +1206,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
return -EFAULT;
}
- if (is_vm_hugetlb_page(vma)) {
+ if (is_vm_hugetlb_page(vma) && !logging_active) {
hugetlb = true;
gfn = (fault_ipa & PMD_MASK) >> PAGE_SHIFT;
} else {
@@ -976,12 +1247,30 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
if (is_error_pfn(pfn))
return -EFAULT;
- if (kvm_is_device_pfn(pfn))
+ if (kvm_is_device_pfn(pfn)) {
mem_type = PAGE_S2_DEVICE;
+ flags |= KVM_S2PTE_FLAG_IS_IOMAP;
+ } else if (logging_active) {
+ /*
+ * Faults on pages in a memslot with logging enabled
+ * should not be mapped with huge pages (it introduces churn
+ * and performance degradation), so force a pte mapping.
+ */
+ force_pte = true;
+ flags |= KVM_S2_FLAG_LOGGING_ACTIVE;
+
+ /*
+ * Only actually map the page as writable if this was a write
+ * fault.
+ */
+ if (!write_fault)
+ writable = false;
+ }
spin_lock(&kvm->mmu_lock);
if (mmu_notifier_retry(kvm, mmu_seq))
goto out_unlock;
+
if (!hugetlb && !force_pte)
hugetlb = transparent_hugepage_adjust(&pfn, &fault_ipa);
@@ -994,22 +1283,20 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,
kvm_set_s2pmd_writable(&new_pmd);
kvm_set_pfn_dirty(pfn);
}
- coherent_cache_guest_page(vcpu, hva & PMD_MASK, PMD_SIZE,
- fault_ipa_uncached);
+ coherent_cache_guest_page(vcpu, pfn, PMD_SIZE, fault_ipa_uncached);
ret = stage2_set_pmd_huge(kvm, memcache, fault_ipa, &new_pmd);
} else {
pte_t new_pte = pfn_pte(pfn, mem_type);
+
if (writable) {
kvm_set_s2pte_writable(&new_pte);
kvm_set_pfn_dirty(pfn);
+ mark_page_dirty(kvm, gfn);
}
- coherent_cache_guest_page(vcpu, hva, PAGE_SIZE,
- fault_ipa_uncached);
- ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte,
- pgprot_val(mem_type) == pgprot_val(PAGE_S2_DEVICE));
+ coherent_cache_guest_page(vcpu, pfn, PAGE_SIZE, fault_ipa_uncached);
+ ret = stage2_set_pte(kvm, memcache, fault_ipa, &new_pte, flags);
}
-
out_unlock:
spin_unlock(&kvm->mmu_lock);
kvm_release_pfn_clean(pfn);
@@ -1159,7 +1446,14 @@ static void kvm_set_spte_handler(struct kvm *kvm, gpa_t gpa, void *data)
{
pte_t *pte = (pte_t *)data;
- stage2_set_pte(kvm, NULL, gpa, pte, false);
+ /*
+ * We can always call stage2_set_pte with KVM_S2PTE_FLAG_LOGGING_ACTIVE
+ * flag clear because MMU notifiers will have unmapped a huge PMD before
+ * calling ->change_pte() (which in turn calls kvm_set_spte_hva()) and
+ * therefore stage2_set_pte() never needs to clear out a huge PMD
+ * through this calling path.
+ */
+ stage2_set_pte(kvm, NULL, gpa, pte, 0);
}
@@ -1292,6 +1586,13 @@ void kvm_arch_commit_memory_region(struct kvm *kvm,
const struct kvm_memory_slot *old,
enum kvm_mr_change change)
{
+ /*
+ * At this point memslot has been committed and there is an
+ * allocated dirty_bitmap[], dirty pages will be be tracked while the
+ * memory slot is write protected.
+ */
+ if (change != KVM_MR_DELETE && mem->flags & KVM_MEM_LOG_DIRTY_PAGES)
+ kvm_mmu_wp_memory_region(kvm, mem->slot);
}
int kvm_arch_prepare_memory_region(struct kvm *kvm,
@@ -1304,7 +1605,8 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
bool writable = !(mem->flags & KVM_MEM_READONLY);
int ret = 0;
- if (change != KVM_MR_CREATE && change != KVM_MR_MOVE)
+ if (change != KVM_MR_CREATE && change != KVM_MR_MOVE &&
+ change != KVM_MR_FLAGS_ONLY)
return 0;
/*
@@ -1355,6 +1657,10 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
phys_addr_t pa = (vma->vm_pgoff << PAGE_SHIFT) +
vm_start - vma->vm_start;
+ /* IO region dirty page logging not allowed */
+ if (memslot->flags & KVM_MEM_LOG_DIRTY_PAGES)
+ return -EINVAL;
+
ret = kvm_phys_addr_ioremap(kvm, gpa, pa,
vm_end - vm_start,
writable);
@@ -1364,6 +1670,9 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm,
hva = vm_end;
} while (hva < reg_end);
+ if (change == KVM_MR_FLAGS_ONLY)
+ return ret;
+
spin_lock(&kvm->mmu_lock);
if (ret)
unmap_stage2_range(kvm, mem->guest_phys_addr, mem->memory_size);
@@ -1411,3 +1720,71 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm,
unmap_stage2_range(kvm, gpa, size);
spin_unlock(&kvm->mmu_lock);
}
+
+/*
+ * See note at ARMv7 ARM B1.14.4 (TL;DR: S/W ops are not easily virtualized).
+ *
+ * Main problems:
+ * - S/W ops are local to a CPU (not broadcast)
+ * - We have line migration behind our back (speculation)
+ * - System caches don't support S/W at all (damn!)
+ *
+ * In the face of the above, the best we can do is to try and convert
+ * S/W ops to VA ops. Because the guest is not allowed to infer the
+ * S/W to PA mapping, it can only use S/W to nuke the whole cache,
+ * which is a rather good thing for us.
+ *
+ * Also, it is only used when turning caches on/off ("The expected
+ * usage of the cache maintenance instructions that operate by set/way
+ * is associated with the cache maintenance instructions associated
+ * with the powerdown and powerup of caches, if this is required by
+ * the implementation.").
+ *
+ * We use the following policy:
+ *
+ * - If we trap a S/W operation, we enable VM trapping to detect
+ * caches being turned on/off, and do a full clean.
+ *
+ * - We flush the caches on both caches being turned on and off.
+ *
+ * - Once the caches are enabled, we stop trapping VM ops.
+ */
+void kvm_set_way_flush(struct kvm_vcpu *vcpu)
+{
+ unsigned long hcr = vcpu_get_hcr(vcpu);
+
+ /*
+ * If this is the first time we do a S/W operation
+ * (i.e. HCR_TVM not set) flush the whole memory, and set the
+ * VM trapping.
+ *
+ * Otherwise, rely on the VM trapping to wait for the MMU +
+ * Caches to be turned off. At that point, we'll be able to
+ * clean the caches again.
+ */
+ if (!(hcr & HCR_TVM)) {
+ trace_kvm_set_way_flush(*vcpu_pc(vcpu),
+ vcpu_has_cache_enabled(vcpu));
+ stage2_flush_vm(vcpu->kvm);
+ vcpu_set_hcr(vcpu, hcr | HCR_TVM);
+ }
+}
+
+void kvm_toggle_cache(struct kvm_vcpu *vcpu, bool was_enabled)
+{
+ bool now_enabled = vcpu_has_cache_enabled(vcpu);
+
+ /*
+ * If switching the MMU+caches on, need to invalidate the caches.
+ * If switching it off, need to clean the caches.
+ * Clean + invalidate does the trick always.
+ */
+ if (now_enabled != was_enabled)
+ stage2_flush_vm(vcpu->kvm);
+
+ /* Caches are now on, stop trapping VM ops (until a S/W op) */
+ if (now_enabled)
+ vcpu_set_hcr(vcpu, vcpu_get_hcr(vcpu) & ~HCR_TVM);
+
+ trace_kvm_toggle_cache(*vcpu_pc(vcpu), was_enabled, now_enabled);
+}
diff --git a/arch/arm/kvm/psci.c b/arch/arm/kvm/psci.c
index 58cb3248d277..02fa8eff6ae1 100644
--- a/arch/arm/kvm/psci.c
+++ b/arch/arm/kvm/psci.c
@@ -22,6 +22,7 @@
#include <asm/cputype.h>
#include <asm/kvm_emulate.h>
#include <asm/kvm_psci.h>
+#include <asm/kvm_host.h>
/*
* This is an implementation of the Power State Coordination Interface
@@ -66,25 +67,17 @@ static void kvm_psci_vcpu_off(struct kvm_vcpu *vcpu)
static unsigned long kvm_psci_vcpu_on(struct kvm_vcpu *source_vcpu)
{
struct kvm *kvm = source_vcpu->kvm;
- struct kvm_vcpu *vcpu = NULL, *tmp;
+ struct kvm_vcpu *vcpu = NULL;
wait_queue_head_t *wq;
unsigned long cpu_id;
unsigned long context_id;
- unsigned long mpidr;
phys_addr_t target_pc;
- int i;
- cpu_id = *vcpu_reg(source_vcpu, 1);
+ cpu_id = *vcpu_reg(source_vcpu, 1) & MPIDR_HWID_BITMASK;
if (vcpu_mode_is_32bit(source_vcpu))
cpu_id &= ~((u32) 0);
- kvm_for_each_vcpu(i, tmp, kvm) {
- mpidr = kvm_vcpu_get_mpidr(tmp);
- if ((mpidr & MPIDR_HWID_BITMASK) == (cpu_id & MPIDR_HWID_BITMASK)) {
- vcpu = tmp;
- break;
- }
- }
+ vcpu = kvm_mpidr_to_vcpu(kvm, cpu_id);
/*
* Make sure the caller requested a valid CPU and that the CPU is
@@ -155,7 +148,7 @@ static unsigned long kvm_psci_vcpu_affinity_info(struct kvm_vcpu *vcpu)
* then ON else OFF
*/
kvm_for_each_vcpu(i, tmp, kvm) {
- mpidr = kvm_vcpu_get_mpidr(tmp);
+ mpidr = kvm_vcpu_get_mpidr_aff(tmp);
if (((mpidr & target_affinity_mask) == target_affinity) &&
!tmp->arch.pause) {
return PSCI_0_2_AFFINITY_LEVEL_ON;
diff --git a/arch/arm/kvm/trace.h b/arch/arm/kvm/trace.h
index b1d640f78623..881874b1a036 100644
--- a/arch/arm/kvm/trace.h
+++ b/arch/arm/kvm/trace.h
@@ -140,19 +140,22 @@ TRACE_EVENT(kvm_emulate_cp15_imp,
__entry->CRm, __entry->Op2)
);
-TRACE_EVENT(kvm_wfi,
- TP_PROTO(unsigned long vcpu_pc),
- TP_ARGS(vcpu_pc),
+TRACE_EVENT(kvm_wfx,
+ TP_PROTO(unsigned long vcpu_pc, bool is_wfe),
+ TP_ARGS(vcpu_pc, is_wfe),
TP_STRUCT__entry(
__field( unsigned long, vcpu_pc )
+ __field( bool, is_wfe )
),
TP_fast_assign(
__entry->vcpu_pc = vcpu_pc;
+ __entry->is_wfe = is_wfe;
),
- TP_printk("guest executed wfi at: 0x%08lx", __entry->vcpu_pc)
+ TP_printk("guest executed wf%c at: 0x%08lx",
+ __entry->is_wfe ? 'e' : 'i', __entry->vcpu_pc)
);
TRACE_EVENT(kvm_unmap_hva,
@@ -223,6 +226,45 @@ TRACE_EVENT(kvm_hvc,
__entry->vcpu_pc, __entry->r0, __entry->imm)
);
+TRACE_EVENT(kvm_set_way_flush,
+ TP_PROTO(unsigned long vcpu_pc, bool cache),
+ TP_ARGS(vcpu_pc, cache),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, vcpu_pc )
+ __field( bool, cache )
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_pc = vcpu_pc;
+ __entry->cache = cache;
+ ),
+
+ TP_printk("S/W flush at 0x%016lx (cache %s)",
+ __entry->vcpu_pc, __entry->cache ? "on" : "off")
+);
+
+TRACE_EVENT(kvm_toggle_cache,
+ TP_PROTO(unsigned long vcpu_pc, bool was, bool now),
+ TP_ARGS(vcpu_pc, was, now),
+
+ TP_STRUCT__entry(
+ __field( unsigned long, vcpu_pc )
+ __field( bool, was )
+ __field( bool, now )
+ ),
+
+ TP_fast_assign(
+ __entry->vcpu_pc = vcpu_pc;
+ __entry->was = was;
+ __entry->now = now;
+ ),
+
+ TP_printk("VM op at 0x%016lx (cache was %s, now %s)",
+ __entry->vcpu_pc, __entry->was ? "on" : "off",
+ __entry->now ? "on" : "off")
+);
+
#endif /* _TRACE_KVM_H */
#undef TRACE_INCLUDE_PATH
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile
index 0573faab96ad..d8a780799506 100644
--- a/arch/arm/lib/Makefile
+++ b/arch/arm/lib/Makefile
@@ -15,19 +15,8 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \
io-readsb.o io-writesb.o io-readsl.o io-writesl.o \
call_with_stack.o bswapsdi2.o
-mmu-y := clear_user.o copy_page.o getuser.o putuser.o
-
-# the code in uaccess.S is not preemption safe and
-# probably faster on ARMv3 only
-ifeq ($(CONFIG_PREEMPT),y)
- mmu-y += copy_from_user.o copy_to_user.o
-else
-ifneq ($(CONFIG_CPU_32v3),y)
- mmu-y += copy_from_user.o copy_to_user.o
-else
- mmu-y += uaccess.o
-endif
-endif
+mmu-y := clear_user.o copy_page.o getuser.o putuser.o \
+ copy_from_user.o copy_to_user.o
# using lib_ here won't override already available weak symbols
obj-$(CONFIG_UACCESS_WITH_MEMCPY) += uaccess_with_memcpy.o
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S
deleted file mode 100644
index e50520904b76..000000000000
--- a/arch/arm/lib/uaccess.S
+++ /dev/null
@@ -1,564 +0,0 @@
-/*
- * linux/arch/arm/lib/uaccess.S
- *
- * Copyright (C) 1995, 1996,1997,1998 Russell King
- *
- * 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.
- *
- * Routines to block copy data to/from user memory
- * These are highly optimised both for the 4k page size
- * and for various alignments.
- */
-#include <linux/linkage.h>
-#include <asm/assembler.h>
-#include <asm/errno.h>
-#include <asm/domain.h>
-
- .text
-
-#define PAGE_SHIFT 12
-
-/* Prototype: int __copy_to_user(void *to, const char *from, size_t n)
- * Purpose : copy a block to user memory from kernel memory
- * Params : to - user memory
- * : from - kernel memory
- * : n - number of bytes to copy
- * Returns : Number of bytes NOT copied.
- */
-
-.Lc2u_dest_not_aligned:
- rsb ip, ip, #4
- cmp ip, #2
- ldrb r3, [r1], #1
-USER( TUSER( strb) r3, [r0], #1) @ May fault
- ldrgeb r3, [r1], #1
-USER( TUSER( strgeb) r3, [r0], #1) @ May fault
- ldrgtb r3, [r1], #1
-USER( TUSER( strgtb) r3, [r0], #1) @ May fault
- sub r2, r2, ip
- b .Lc2u_dest_aligned
-
-ENTRY(__copy_to_user)
- stmfd sp!, {r2, r4 - r7, lr}
- cmp r2, #4
- blt .Lc2u_not_enough
- ands ip, r0, #3
- bne .Lc2u_dest_not_aligned
-.Lc2u_dest_aligned:
-
- ands ip, r1, #3
- bne .Lc2u_src_not_aligned
-/*
- * Seeing as there has to be at least 8 bytes to copy, we can
- * copy one word, and force a user-mode page fault...
- */
-
-.Lc2u_0fupi: subs r2, r2, #4
- addmi ip, r2, #4
- bmi .Lc2u_0nowords
- ldr r3, [r1], #4
-USER( TUSER( str) r3, [r0], #4) @ May fault
- mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
- rsb ip, ip, #0
- movs ip, ip, lsr #32 - PAGE_SHIFT
- beq .Lc2u_0fupi
-/*
- * ip = max no. of bytes to copy before needing another "strt" insn
- */
- cmp r2, ip
- movlt ip, r2
- sub r2, r2, ip
- subs ip, ip, #32
- blt .Lc2u_0rem8lp
-
-.Lc2u_0cpy8lp: ldmia r1!, {r3 - r6}
- stmia r0!, {r3 - r6} @ Shouldnt fault
- ldmia r1!, {r3 - r6}
- subs ip, ip, #32
- stmia r0!, {r3 - r6} @ Shouldnt fault
- bpl .Lc2u_0cpy8lp
-
-.Lc2u_0rem8lp: cmn ip, #16
- ldmgeia r1!, {r3 - r6}
- stmgeia r0!, {r3 - r6} @ Shouldnt fault
- tst ip, #8
- ldmneia r1!, {r3 - r4}
- stmneia r0!, {r3 - r4} @ Shouldnt fault
- tst ip, #4
- ldrne r3, [r1], #4
- TUSER( strne) r3, [r0], #4 @ Shouldnt fault
- ands ip, ip, #3
- beq .Lc2u_0fupi
-.Lc2u_0nowords: teq ip, #0
- beq .Lc2u_finished
-.Lc2u_nowords: cmp ip, #2
- ldrb r3, [r1], #1
-USER( TUSER( strb) r3, [r0], #1) @ May fault
- ldrgeb r3, [r1], #1
-USER( TUSER( strgeb) r3, [r0], #1) @ May fault
- ldrgtb r3, [r1], #1
-USER( TUSER( strgtb) r3, [r0], #1) @ May fault
- b .Lc2u_finished
-
-.Lc2u_not_enough:
- movs ip, r2
- bne .Lc2u_nowords
-.Lc2u_finished: mov r0, #0
- ldmfd sp!, {r2, r4 - r7, pc}
-
-.Lc2u_src_not_aligned:
- bic r1, r1, #3
- ldr r7, [r1], #4
- cmp ip, #2
- bgt .Lc2u_3fupi
- beq .Lc2u_2fupi
-.Lc2u_1fupi: subs r2, r2, #4
- addmi ip, r2, #4
- bmi .Lc2u_1nowords
- mov r3, r7, lspull #8
- ldr r7, [r1], #4
- orr r3, r3, r7, lspush #24
-USER( TUSER( str) r3, [r0], #4) @ May fault
- mov ip, r0, lsl #32 - PAGE_SHIFT
- rsb ip, ip, #0
- movs ip, ip, lsr #32 - PAGE_SHIFT
- beq .Lc2u_1fupi
- cmp r2, ip
- movlt ip, r2
- sub r2, r2, ip
- subs ip, ip, #16
- blt .Lc2u_1rem8lp
-
-.Lc2u_1cpy8lp: mov r3, r7, lspull #8
- ldmia r1!, {r4 - r7}
- subs ip, ip, #16
- orr r3, r3, r4, lspush #24
- mov r4, r4, lspull #8
- orr r4, r4, r5, lspush #24
- mov r5, r5, lspull #8
- orr r5, r5, r6, lspush #24
- mov r6, r6, lspull #8
- orr r6, r6, r7, lspush #24
- stmia r0!, {r3 - r6} @ Shouldnt fault
- bpl .Lc2u_1cpy8lp
-
-.Lc2u_1rem8lp: tst ip, #8
- movne r3, r7, lspull #8
- ldmneia r1!, {r4, r7}
- orrne r3, r3, r4, lspush #24
- movne r4, r4, lspull #8
- orrne r4, r4, r7, lspush #24
- stmneia r0!, {r3 - r4} @ Shouldnt fault
- tst ip, #4
- movne r3, r7, lspull #8
- ldrne r7, [r1], #4
- orrne r3, r3, r7, lspush #24
- TUSER( strne) r3, [r0], #4 @ Shouldnt fault
- ands ip, ip, #3
- beq .Lc2u_1fupi
-.Lc2u_1nowords: mov r3, r7, get_byte_1
- teq ip, #0
- beq .Lc2u_finished
- cmp ip, #2
-USER( TUSER( strb) r3, [r0], #1) @ May fault
- movge r3, r7, get_byte_2
-USER( TUSER( strgeb) r3, [r0], #1) @ May fault
- movgt r3, r7, get_byte_3
-USER( TUSER( strgtb) r3, [r0], #1) @ May fault
- b .Lc2u_finished
-
-.Lc2u_2fupi: subs r2, r2, #4
- addmi ip, r2, #4
- bmi .Lc2u_2nowords
- mov r3, r7, lspull #16
- ldr r7, [r1], #4
- orr r3, r3, r7, lspush #16
-USER( TUSER( str) r3, [r0], #4) @ May fault
- mov ip, r0, lsl #32 - PAGE_SHIFT
- rsb ip, ip, #0
- movs ip, ip, lsr #32 - PAGE_SHIFT
- beq .Lc2u_2fupi
- cmp r2, ip
- movlt ip, r2
- sub r2, r2, ip
- subs ip, ip, #16
- blt .Lc2u_2rem8lp
-
-.Lc2u_2cpy8lp: mov r3, r7, lspull #16
- ldmia r1!, {r4 - r7}
- subs ip, ip, #16
- orr r3, r3, r4, lspush #16
- mov r4, r4, lspull #16
- orr r4, r4, r5, lspush #16
- mov r5, r5, lspull #16
- orr r5, r5, r6, lspush #16
- mov r6, r6, lspull #16
- orr r6, r6, r7, lspush #16
- stmia r0!, {r3 - r6} @ Shouldnt fault
- bpl .Lc2u_2cpy8lp
-
-.Lc2u_2rem8lp: tst ip, #8
- movne r3, r7, lspull #16
- ldmneia r1!, {r4, r7}
- orrne r3, r3, r4, lspush #16
- movne r4, r4, lspull #16
- orrne r4, r4, r7, lspush #16
- stmneia r0!, {r3 - r4} @ Shouldnt fault
- tst ip, #4
- movne r3, r7, lspull #16
- ldrne r7, [r1], #4
- orrne r3, r3, r7, lspush #16
- TUSER( strne) r3, [r0], #4 @ Shouldnt fault
- ands ip, ip, #3
- beq .Lc2u_2fupi
-.Lc2u_2nowords: mov r3, r7, get_byte_2
- teq ip, #0
- beq .Lc2u_finished
- cmp ip, #2
-USER( TUSER( strb) r3, [r0], #1) @ May fault
- movge r3, r7, get_byte_3
-USER( TUSER( strgeb) r3, [r0], #1) @ May fault
- ldrgtb r3, [r1], #0
-USER( TUSER( strgtb) r3, [r0], #1) @ May fault
- b .Lc2u_finished
-
-.Lc2u_3fupi: subs r2, r2, #4
- addmi ip, r2, #4
- bmi .Lc2u_3nowords
- mov r3, r7, lspull #24
- ldr r7, [r1], #4
- orr r3, r3, r7, lspush #8
-USER( TUSER( str) r3, [r0], #4) @ May fault
- mov ip, r0, lsl #32 - PAGE_SHIFT
- rsb ip, ip, #0
- movs ip, ip, lsr #32 - PAGE_SHIFT
- beq .Lc2u_3fupi
- cmp r2, ip
- movlt ip, r2
- sub r2, r2, ip
- subs ip, ip, #16
- blt .Lc2u_3rem8lp
-
-.Lc2u_3cpy8lp: mov r3, r7, lspull #24
- ldmia r1!, {r4 - r7}
- subs ip, ip, #16
- orr r3, r3, r4, lspush #8
- mov r4, r4, lspull #24
- orr r4, r4, r5, lspush #8
- mov r5, r5, lspull #24
- orr r5, r5, r6, lspush #8
- mov r6, r6, lspull #24
- orr r6, r6, r7, lspush #8
- stmia r0!, {r3 - r6} @ Shouldnt fault
- bpl .Lc2u_3cpy8lp
-
-.Lc2u_3rem8lp: tst ip, #8
- movne r3, r7, lspull #24
- ldmneia r1!, {r4, r7}
- orrne r3, r3, r4, lspush #8
- movne r4, r4, lspull #24
- orrne r4, r4, r7, lspush #8
- stmneia r0!, {r3 - r4} @ Shouldnt fault
- tst ip, #4
- movne r3, r7, lspull #24
- ldrne r7, [r1], #4
- orrne r3, r3, r7, lspush #8
- TUSER( strne) r3, [r0], #4 @ Shouldnt fault
- ands ip, ip, #3
- beq .Lc2u_3fupi
-.Lc2u_3nowords: mov r3, r7, get_byte_3
- teq ip, #0
- beq .Lc2u_finished
- cmp ip, #2
-USER( TUSER( strb) r3, [r0], #1) @ May fault
- ldrgeb r3, [r1], #1
-USER( TUSER( strgeb) r3, [r0], #1) @ May fault
- ldrgtb r3, [r1], #0
-USER( TUSER( strgtb) r3, [r0], #1) @ May fault
- b .Lc2u_finished
-ENDPROC(__copy_to_user)
-
- .pushsection .fixup,"ax"
- .align 0
-9001: ldmfd sp!, {r0, r4 - r7, pc}
- .popsection
-
-/* Prototype: unsigned long __copy_from_user(void *to,const void *from,unsigned long n);
- * Purpose : copy a block from user memory to kernel memory
- * Params : to - kernel memory
- * : from - user memory
- * : n - number of bytes to copy
- * Returns : Number of bytes NOT copied.
- */
-.Lcfu_dest_not_aligned:
- rsb ip, ip, #4
- cmp ip, #2
-USER( TUSER( ldrb) r3, [r1], #1) @ May fault
- strb r3, [r0], #1
-USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault
- strgeb r3, [r0], #1
-USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault
- strgtb r3, [r0], #1
- sub r2, r2, ip
- b .Lcfu_dest_aligned
-
-ENTRY(__copy_from_user)
- stmfd sp!, {r0, r2, r4 - r7, lr}
- cmp r2, #4
- blt .Lcfu_not_enough
- ands ip, r0, #3
- bne .Lcfu_dest_not_aligned
-.Lcfu_dest_aligned:
- ands ip, r1, #3
- bne .Lcfu_src_not_aligned
-
-/*
- * Seeing as there has to be at least 8 bytes to copy, we can
- * copy one word, and force a user-mode page fault...
- */
-
-.Lcfu_0fupi: subs r2, r2, #4
- addmi ip, r2, #4
- bmi .Lcfu_0nowords
-USER( TUSER( ldr) r3, [r1], #4)
- str r3, [r0], #4
- mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction
- rsb ip, ip, #0
- movs ip, ip, lsr #32 - PAGE_SHIFT
- beq .Lcfu_0fupi
-/*
- * ip = max no. of bytes to copy before needing another "strt" insn
- */
- cmp r2, ip
- movlt ip, r2
- sub r2, r2, ip
- subs ip, ip, #32
- blt .Lcfu_0rem8lp
-
-.Lcfu_0cpy8lp: ldmia r1!, {r3 - r6} @ Shouldnt fault
- stmia r0!, {r3 - r6}
- ldmia r1!, {r3 - r6} @ Shouldnt fault
- subs ip, ip, #32
- stmia r0!, {r3 - r6}
- bpl .Lcfu_0cpy8lp
-
-.Lcfu_0rem8lp: cmn ip, #16
- ldmgeia r1!, {r3 - r6} @ Shouldnt fault
- stmgeia r0!, {r3 - r6}
- tst ip, #8
- ldmneia r1!, {r3 - r4} @ Shouldnt fault
- stmneia r0!, {r3 - r4}
- tst ip, #4
- TUSER( ldrne) r3, [r1], #4 @ Shouldnt fault
- strne r3, [r0], #4
- ands ip, ip, #3
- beq .Lcfu_0fupi
-.Lcfu_0nowords: teq ip, #0
- beq .Lcfu_finished
-.Lcfu_nowords: cmp ip, #2
-USER( TUSER( ldrb) r3, [r1], #1) @ May fault
- strb r3, [r0], #1
-USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault
- strgeb r3, [r0], #1
-USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault
- strgtb r3, [r0], #1
- b .Lcfu_finished
-
-.Lcfu_not_enough:
- movs ip, r2
- bne .Lcfu_nowords
-.Lcfu_finished: mov r0, #0
- add sp, sp, #8
- ldmfd sp!, {r4 - r7, pc}
-
-.Lcfu_src_not_aligned:
- bic r1, r1, #3
-USER( TUSER( ldr) r7, [r1], #4) @ May fault
- cmp ip, #2
- bgt .Lcfu_3fupi
- beq .Lcfu_2fupi
-.Lcfu_1fupi: subs r2, r2, #4
- addmi ip, r2, #4
- bmi .Lcfu_1nowords
- mov r3, r7, lspull #8
-USER( TUSER( ldr) r7, [r1], #4) @ May fault
- orr r3, r3, r7, lspush #24
- str r3, [r0], #4
- mov ip, r1, lsl #32 - PAGE_SHIFT
- rsb ip, ip, #0
- movs ip, ip, lsr #32 - PAGE_SHIFT
- beq .Lcfu_1fupi
- cmp r2, ip
- movlt ip, r2
- sub r2, r2, ip
- subs ip, ip, #16
- blt .Lcfu_1rem8lp
-
-.Lcfu_1cpy8lp: mov r3, r7, lspull #8
- ldmia r1!, {r4 - r7} @ Shouldnt fault
- subs ip, ip, #16
- orr r3, r3, r4, lspush #24
- mov r4, r4, lspull #8
- orr r4, r4, r5, lspush #24
- mov r5, r5, lspull #8
- orr r5, r5, r6, lspush #24
- mov r6, r6, lspull #8
- orr r6, r6, r7, lspush #24
- stmia r0!, {r3 - r6}
- bpl .Lcfu_1cpy8lp
-
-.Lcfu_1rem8lp: tst ip, #8
- movne r3, r7, lspull #8
- ldmneia r1!, {r4, r7} @ Shouldnt fault
- orrne r3, r3, r4, lspush #24
- movne r4, r4, lspull #8
- orrne r4, r4, r7, lspush #24
- stmneia r0!, {r3 - r4}
- tst ip, #4
- movne r3, r7, lspull #8
-USER( TUSER( ldrne) r7, [r1], #4) @ May fault
- orrne r3, r3, r7, lspush #24
- strne r3, [r0], #4
- ands ip, ip, #3
- beq .Lcfu_1fupi
-.Lcfu_1nowords: mov r3, r7, get_byte_1
- teq ip, #0
- beq .Lcfu_finished
- cmp ip, #2
- strb r3, [r0], #1
- movge r3, r7, get_byte_2
- strgeb r3, [r0], #1
- movgt r3, r7, get_byte_3
- strgtb r3, [r0], #1
- b .Lcfu_finished
-
-.Lcfu_2fupi: subs r2, r2, #4
- addmi ip, r2, #4
- bmi .Lcfu_2nowords
- mov r3, r7, lspull #16
-USER( TUSER( ldr) r7, [r1], #4) @ May fault
- orr r3, r3, r7, lspush #16
- str r3, [r0], #4
- mov ip, r1, lsl #32 - PAGE_SHIFT
- rsb ip, ip, #0
- movs ip, ip, lsr #32 - PAGE_SHIFT
- beq .Lcfu_2fupi
- cmp r2, ip
- movlt ip, r2
- sub r2, r2, ip
- subs ip, ip, #16
- blt .Lcfu_2rem8lp
-
-
-.Lcfu_2cpy8lp: mov r3, r7, lspull #16
- ldmia r1!, {r4 - r7} @ Shouldnt fault
- subs ip, ip, #16
- orr r3, r3, r4, lspush #16
- mov r4, r4, lspull #16
- orr r4, r4, r5, lspush #16
- mov r5, r5, lspull #16
- orr r5, r5, r6, lspush #16
- mov r6, r6, lspull #16
- orr r6, r6, r7, lspush #16
- stmia r0!, {r3 - r6}
- bpl .Lcfu_2cpy8lp
-
-.Lcfu_2rem8lp: tst ip, #8
- movne r3, r7, lspull #16
- ldmneia r1!, {r4, r7} @ Shouldnt fault
- orrne r3, r3, r4, lspush #16
- movne r4, r4, lspull #16
- orrne r4, r4, r7, lspush #16
- stmneia r0!, {r3 - r4}
- tst ip, #4
- movne r3, r7, lspull #16
-USER( TUSER( ldrne) r7, [r1], #4) @ May fault
- orrne r3, r3, r7, lspush #16
- strne r3, [r0], #4
- ands ip, ip, #3
- beq .Lcfu_2fupi
-.Lcfu_2nowords: mov r3, r7, get_byte_2
- teq ip, #0
- beq .Lcfu_finished
- cmp ip, #2
- strb r3, [r0], #1
- movge r3, r7, get_byte_3
- strgeb r3, [r0], #1
-USER( TUSER( ldrgtb) r3, [r1], #0) @ May fault
- strgtb r3, [r0], #1
- b .Lcfu_finished
-
-.Lcfu_3fupi: subs r2, r2, #4
- addmi ip, r2, #4
- bmi .Lcfu_3nowords
- mov r3, r7, lspull #24
-USER( TUSER( ldr) r7, [r1], #4) @ May fault
- orr r3, r3, r7, lspush #8
- str r3, [r0], #4
- mov ip, r1, lsl #32 - PAGE_SHIFT
- rsb ip, ip, #0
- movs ip, ip, lsr #32 - PAGE_SHIFT
- beq .Lcfu_3fupi
- cmp r2, ip
- movlt ip, r2
- sub r2, r2, ip
- subs ip, ip, #16
- blt .Lcfu_3rem8lp
-
-.Lcfu_3cpy8lp: mov r3, r7, lspull #24
- ldmia r1!, {r4 - r7} @ Shouldnt fault
- orr r3, r3, r4, lspush #8
- mov r4, r4, lspull #24
- orr r4, r4, r5, lspush #8
- mov r5, r5, lspull #24
- orr r5, r5, r6, lspush #8
- mov r6, r6, lspull #24
- orr r6, r6, r7, lspush #8
- stmia r0!, {r3 - r6}
- subs ip, ip, #16
- bpl .Lcfu_3cpy8lp
-
-.Lcfu_3rem8lp: tst ip, #8
- movne r3, r7, lspull #24
- ldmneia r1!, {r4, r7} @ Shouldnt fault
- orrne r3, r3, r4, lspush #8
- movne r4, r4, lspull #24
- orrne r4, r4, r7, lspush #8
- stmneia r0!, {r3 - r4}
- tst ip, #4
- movne r3, r7, lspull #24
-USER( TUSER( ldrne) r7, [r1], #4) @ May fault
- orrne r3, r3, r7, lspush #8
- strne r3, [r0], #4
- ands ip, ip, #3
- beq .Lcfu_3fupi
-.Lcfu_3nowords: mov r3, r7, get_byte_3
- teq ip, #0
- beq .Lcfu_finished
- cmp ip, #2
- strb r3, [r0], #1
-USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault
- strgeb r3, [r0], #1
-USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault
- strgtb r3, [r0], #1
- b .Lcfu_finished
-ENDPROC(__copy_from_user)
-
- .pushsection .fixup,"ax"
- .align 0
- /*
- * We took an exception. r0 contains a pointer to
- * the byte not copied.
- */
-9001: ldr r2, [sp], #4 @ void *to
- sub r2, r0, r2 @ bytes copied
- ldr r1, [sp], #4 @ unsigned long count
- subs r4, r1, r2 @ bytes left to copy
- movne r1, r4
- blne __memzero
- mov r0, r4
- ldmfd sp!, {r4 - r7, pc}
- .popsection
-
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 2395c68b3e32..c6740e359a44 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -6,15 +6,6 @@ config HAVE_AT91_UTMI
config HAVE_AT91_USB_CLK
bool
-config HAVE_AT91_DBGU0
- bool
-
-config HAVE_AT91_DBGU1
- bool
-
-config HAVE_AT91_DBGU2
- bool
-
config COMMON_CLK_AT91
bool
select COMMON_CLK
@@ -25,15 +16,6 @@ config HAVE_AT91_SMD
config HAVE_AT91_H32MX
bool
-config SOC_AT91SAM9
- bool
- select ATMEL_AIC_IRQ
- select COMMON_CLK_AT91
- select CPU_ARM926T
- select GENERIC_CLOCKEVENTS
- select MEMORY
- select ATMEL_SDRAMC
-
config SOC_SAMA5
bool
select ATMEL_AIC5_IRQ
@@ -70,7 +52,6 @@ config SOC_SAMA5D3
bool "SAMA5D3 family"
select SOC_SAMA5
select HAVE_FB_ATMEL
- select HAVE_AT91_DBGU1
select HAVE_AT91_UTMI
select HAVE_AT91_SMD
select HAVE_AT91_USB_CLK
@@ -81,7 +62,6 @@ config SOC_SAMA5D3
config SOC_SAMA5D4
bool "SAMA5D4 family"
select SOC_SAMA5
- select HAVE_AT91_DBGU2
select CLKSRC_MMIO
select CACHE_L2X0
select CACHE_PL310
@@ -101,91 +81,45 @@ config SOC_AT91RM9200
select COMMON_CLK_AT91
select CPU_ARM920T
select GENERIC_CLOCKEVENTS
- select HAVE_AT91_DBGU0
- select HAVE_AT91_USB_CLK
-
-config SOC_AT91SAM9260
- bool "AT91SAM9260, AT91SAM9XE or AT91SAM9G20"
- select HAVE_AT91_DBGU0
- select SOC_AT91SAM9
- select HAVE_AT91_USB_CLK
- help
- Select this if you are using one of Atmel's AT91SAM9260, AT91SAM9XE
- or AT91SAM9G20 SoC.
-
-config SOC_AT91SAM9261
- bool "AT91SAM9261 or AT91SAM9G10"
- select HAVE_AT91_DBGU0
- select HAVE_FB_ATMEL
- select SOC_AT91SAM9
- select HAVE_AT91_USB_CLK
- help
- Select this if you are using one of Atmel's AT91SAM9261 or AT91SAM9G10 SoC.
-
-config SOC_AT91SAM9263
- bool "AT91SAM9263"
- select HAVE_AT91_DBGU1
- select HAVE_FB_ATMEL
- select SOC_AT91SAM9
select HAVE_AT91_USB_CLK
-config SOC_AT91SAM9RL
- bool "AT91SAM9RL"
- select HAVE_AT91_DBGU0
- select HAVE_FB_ATMEL
- select SOC_AT91SAM9
- select HAVE_AT91_UTMI
-
-config SOC_AT91SAM9G45
- bool "AT91SAM9G45 or AT91SAM9M10 families"
- select HAVE_AT91_DBGU1
- select HAVE_FB_ATMEL
- select SOC_AT91SAM9
- select HAVE_AT91_UTMI
- select HAVE_AT91_USB_CLK
- help
- Select this if you are using one of Atmel's AT91SAM9G45 family SoC.
- This support covers AT91SAM9G45, AT91SAM9G46, AT91SAM9M10 and AT91SAM9M11.
-
-config SOC_AT91SAM9X5
- bool "AT91SAM9x5 family"
- select HAVE_AT91_DBGU0
- select HAVE_FB_ATMEL
- select SOC_AT91SAM9
- select HAVE_AT91_UTMI
+config SOC_AT91SAM9
+ bool "AT91SAM9"
+ select ATMEL_AIC_IRQ
+ select ATMEL_SDRAMC
+ select COMMON_CLK_AT91
+ select CPU_ARM926T
+ select GENERIC_CLOCKEVENTS
select HAVE_AT91_SMD
select HAVE_AT91_USB_CLK
- help
- Select this if you are using one of Atmel's AT91SAM9x5 family SoC.
- This means that your SAM9 name finishes with a '5' (except if it is
- AT91SAM9G45!).
- This support covers AT91SAM9G15, AT91SAM9G25, AT91SAM9X25, AT91SAM9G35
- and AT91SAM9X35.
-
-config SOC_AT91SAM9N12
- bool "AT91SAM9N12 family"
- select HAVE_AT91_DBGU0
+ select HAVE_AT91_UTMI
select HAVE_FB_ATMEL
- select SOC_AT91SAM9
- select HAVE_AT91_USB_CLK
+ select MEMORY
help
- Select this if you are using Atmel's AT91SAM9N12 SoC.
-
-# ----------------------------------------------------------
+ Select this if you are using one of those Atmel SoC:
+ AT91SAM9260
+ AT91SAM9261
+ AT91SAM9263
+ AT91SAM9G15
+ AT91SAM9G20
+ AT91SAM9G25
+ AT91SAM9G35
+ AT91SAM9G45
+ AT91SAM9G46
+ AT91SAM9M10
+ AT91SAM9M11
+ AT91SAM9N12
+ AT91SAM9RL
+ AT91SAM9X25
+ AT91SAM9X35
+ AT91SAM9XE
endif # SOC_SAM_V4_V5
-config MACH_AT91RM9200_DT
- def_bool SOC_AT91RM9200
-
-config MACH_AT91SAM9_DT
- def_bool SOC_AT91SAM9
-
-# ----------------------------------------------------------
-
comment "AT91 Feature Selections"
config AT91_SLOW_CLOCK
bool "Suspend-to-RAM disables main oscillator"
+ select SRAM
depends on SUSPEND
help
Select this if you want Suspend-to-RAM to save the most power
diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile
index 7b6424d40764..827fdbcce1c7 100644
--- a/arch/arm/mach-at91/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -2,28 +2,14 @@
# Makefile for the linux kernel.
#
-obj-y := setup.o sysirq_mask.o
+obj-y := setup.o
obj-$(CONFIG_SOC_AT91SAM9) += sam9_smc.o
# CPU-specific support
obj-$(CONFIG_SOC_AT91RM9200) += at91rm9200.o at91rm9200_time.o
-obj-$(CONFIG_SOC_AT91SAM9260) += at91sam9260.o
-obj-$(CONFIG_SOC_AT91SAM9261) += at91sam9261.o
-obj-$(CONFIG_SOC_AT91SAM9263) += at91sam9263.o
-obj-$(CONFIG_SOC_AT91SAM9G45) += at91sam9g45.o
-obj-$(CONFIG_SOC_AT91SAM9N12) += at91sam9n12.o
-obj-$(CONFIG_SOC_AT91SAM9X5) += at91sam9x5.o
-obj-$(CONFIG_SOC_AT91SAM9RL) += at91sam9rl.o
-obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o
-obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o
-
-# AT91SAM board with device-tree
-obj-$(CONFIG_MACH_AT91RM9200_DT) += board-dt-rm9200.o
-obj-$(CONFIG_MACH_AT91SAM9_DT) += board-dt-sam9.o
-
-# SAMA5 board with device-tree
-obj-$(CONFIG_SOC_SAMA5) += board-dt-sama5.o
+obj-$(CONFIG_SOC_AT91SAM9) += at91sam9.o
+obj-$(CONFIG_SOC_SAMA5) += sama5.o
# Power Management
obj-$(CONFIG_PM) += pm.o
diff --git a/arch/arm/mach-at91/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index b52916947535..8fcfb70f7124 100644
--- a/arch/arm/mach-at91/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -1,35 +1,33 @@
/*
- * arch/arm/mach-at91/at91rm9200.c
+ * Setup code for AT91RM9200
*
- * Copyright (C) 2005 SAN People
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
+ * Copyright (C) 2011 Atmel,
+ * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
+ * 2012 Joachim Eastwood <manabian@gmail.com>
*
+ * Licensed under GPLv2 or later.
*/
+#include <linux/types.h>
+#include <linux/init.h>
#include <linux/module.h>
-#include <linux/clk/at91_pmc.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/clk-provider.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
#include <asm/system_misc.h>
+
#include <mach/at91_st.h>
-#include <mach/hardware.h>
-#include "soc.h"
#include "generic.h"
-static void at91rm9200_idle(void)
-{
- /*
- * Disable the processor clock. The processor will be automatically
- * re-enabled by an interrupt or by a reset.
- */
- at91_pmc_write(AT91_PMC_SCDR, AT91_PMC_PCK);
-}
-
static void at91rm9200_restart(enum reboot_mode reboot_mode, const char *cmd)
{
/*
@@ -39,23 +37,31 @@ static void at91rm9200_restart(enum reboot_mode reboot_mode, const char *cmd)
at91_st_write(AT91_ST_CR, AT91_ST_WDRST);
}
-/* --------------------------------------------------------------------
- * AT91RM9200 processor initialization
- * -------------------------------------------------------------------- */
-static void __init at91rm9200_map_io(void)
+static void __init at91rm9200_dt_timer_init(void)
{
- /* Map peripherals */
- at91_init_sram(0, AT91RM9200_SRAM_BASE, AT91RM9200_SRAM_SIZE);
+ of_clk_init(NULL);
+ at91rm9200_timer_init();
}
-static void __init at91rm9200_initialize(void)
+static void __init at91rm9200_dt_device_init(void)
{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
arm_pm_idle = at91rm9200_idle;
arm_pm_restart = at91rm9200_restart;
+ at91rm9200_pm_init();
}
-AT91_SOC_START(at91rm9200)
- .map_io = at91rm9200_map_io,
- .init = at91rm9200_initialize,
-AT91_SOC_END
+
+static const char *at91rm9200_dt_board_compat[] __initconst = {
+ "atmel,at91rm9200",
+ NULL
+};
+
+DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200")
+ .init_time = at91rm9200_dt_timer_init,
+ .map_io = at91_map_io,
+ .init_machine = at91rm9200_dt_device_init,
+ .dt_compat = at91rm9200_dt_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-at91/at91sam9.c b/arch/arm/mach-at91/at91sam9.c
new file mode 100644
index 000000000000..56e3ba73ec40
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9.c
@@ -0,0 +1,87 @@
+/*
+ * Setup code for AT91SAM9
+ *
+ * Copyright (C) 2011 Atmel,
+ * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/clk-provider.h>
+
+#include <asm/system_misc.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include "generic.h"
+
+static void __init at91sam9_dt_device_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
+ arm_pm_idle = at91sam9_idle;
+ at91sam9260_pm_init();
+}
+
+static const char *at91_dt_board_compat[] __initconst = {
+ "atmel,at91sam9",
+ NULL
+};
+
+DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM9")
+ /* Maintainer: Atmel */
+ .map_io = at91_map_io,
+ .init_machine = at91sam9_dt_device_init,
+ .dt_compat = at91_dt_board_compat,
+MACHINE_END
+
+static void __init at91sam9g45_dt_device_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
+ arm_pm_idle = at91sam9_idle;
+ at91sam9g45_pm_init();
+}
+
+static const char *at91sam9g45_board_compat[] __initconst = {
+ "atmel,at91sam9g45",
+ NULL
+};
+
+DT_MACHINE_START(at91sam9g45_dt, "Atmel AT91SAM9G45")
+ /* Maintainer: Atmel */
+ .map_io = at91_map_io,
+ .init_machine = at91sam9g45_dt_device_init,
+ .dt_compat = at91sam9g45_board_compat,
+MACHINE_END
+
+static void __init at91sam9x5_dt_device_init(void)
+{
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+
+ arm_pm_idle = at91sam9_idle;
+ at91sam9x5_pm_init();
+}
+
+static const char *at91sam9x5_board_compat[] __initconst = {
+ "atmel,at91sam9x5",
+ "atmel,at91sam9n12",
+ NULL
+};
+
+DT_MACHINE_START(at91sam9x5_dt, "Atmel AT91SAM9")
+ /* Maintainer: Atmel */
+ .map_io = at91_map_io,
+ .init_machine = at91sam9x5_dt_device_init,
+ .dt_compat = at91sam9x5_board_compat,
+MACHINE_END
diff --git a/arch/arm/mach-at91/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
deleted file mode 100644
index 78137c24d90b..000000000000
--- a/arch/arm/mach-at91/at91sam9260.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * arch/arm/mach-at91/at91sam9260.c
- *
- * Copyright (C) 2006 SAN People
- *
- * This program is free software; you can redistribute it 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/system_misc.h>
-#include <mach/cpu.h>
-#include <mach/at91_dbgu.h>
-#include <mach/hardware.h>
-
-#include "soc.h"
-#include "generic.h"
-
-/* --------------------------------------------------------------------
- * AT91SAM9260 processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init at91sam9xe_map_io(void)
-{
- unsigned long sram_size;
-
- switch (at91_soc_initdata.cidr & AT91_CIDR_SRAMSIZ) {
- case AT91_CIDR_SRAMSIZ_32K:
- sram_size = 2 * SZ_16K;
- break;
- case AT91_CIDR_SRAMSIZ_16K:
- default:
- sram_size = SZ_16K;
- }
-
- at91_init_sram(0, AT91SAM9XE_SRAM_BASE, sram_size);
-}
-
-static void __init at91sam9260_map_io(void)
-{
- if (cpu_is_at91sam9xe())
- at91sam9xe_map_io();
- else if (cpu_is_at91sam9g20())
- at91_init_sram(0, AT91SAM9G20_SRAM_BASE, AT91SAM9G20_SRAM_SIZE);
- else
- at91_init_sram(0, AT91SAM9260_SRAM_BASE, AT91SAM9260_SRAM_SIZE);
-}
-
-static void __init at91sam9260_initialize(void)
-{
- arm_pm_idle = at91sam9_idle;
-
- at91_sysirq_mask_rtt(AT91SAM9260_BASE_RTT);
-}
-
-AT91_SOC_START(at91sam9260)
- .map_io = at91sam9260_map_io,
- .init = at91sam9260_initialize,
-AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
deleted file mode 100644
index d29953ecb0c4..000000000000
--- a/arch/arm/mach-at91/at91sam9261.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * arch/arm/mach-at91/at91sam9261.c
- *
- * Copyright (C) 2005 SAN People
- *
- * This program is free software; you can redistribute it 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/system_misc.h>
-#include <mach/cpu.h>
-#include <mach/hardware.h>
-
-#include "soc.h"
-#include "generic.h"
-
-/* --------------------------------------------------------------------
- * AT91SAM9261 processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init at91sam9261_map_io(void)
-{
- if (cpu_is_at91sam9g10())
- at91_init_sram(0, AT91SAM9G10_SRAM_BASE, AT91SAM9G10_SRAM_SIZE);
- else
- at91_init_sram(0, AT91SAM9261_SRAM_BASE, AT91SAM9261_SRAM_SIZE);
-}
-
-static void __init at91sam9261_initialize(void)
-{
- arm_pm_idle = at91sam9_idle;
-
- at91_sysirq_mask_rtt(AT91SAM9261_BASE_RTT);
-}
-
-AT91_SOC_START(at91sam9261)
- .map_io = at91sam9261_map_io,
- .init = at91sam9261_initialize,
-AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
deleted file mode 100644
index e7ad14864083..000000000000
--- a/arch/arm/mach-at91/at91sam9263.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * arch/arm/mach-at91/at91sam9263.c
- *
- * Copyright (C) 2007 Atmel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <asm/system_misc.h>
-#include <mach/hardware.h>
-
-#include "soc.h"
-#include "generic.h"
-
-/* --------------------------------------------------------------------
- * AT91SAM9263 processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init at91sam9263_map_io(void)
-{
- at91_init_sram(0, AT91SAM9263_SRAM0_BASE, AT91SAM9263_SRAM0_SIZE);
- at91_init_sram(1, AT91SAM9263_SRAM1_BASE, AT91SAM9263_SRAM1_SIZE);
-}
-
-static void __init at91sam9263_initialize(void)
-{
- arm_pm_idle = at91sam9_idle;
-
- at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT0);
- at91_sysirq_mask_rtt(AT91SAM9263_BASE_RTT1);
-}
-
-AT91_SOC_START(at91sam9263)
- .map_io = at91sam9263_map_io,
- .init = at91sam9263_initialize,
-AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9g45.c b/arch/arm/mach-at91/at91sam9g45.c
deleted file mode 100644
index b6117bea9a6f..000000000000
--- a/arch/arm/mach-at91/at91sam9g45.c
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Chip-specific setup code for the AT91SAM9G45 family
- *
- * Copyright (C) 2009 Atmel Corporation.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- */
-
-#include <asm/system_misc.h>
-#include <asm/irq.h>
-#include <mach/hardware.h>
-
-#include "soc.h"
-#include "generic.h"
-
-/* --------------------------------------------------------------------
- * AT91SAM9G45 processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init at91sam9g45_map_io(void)
-{
- at91_init_sram(0, AT91SAM9G45_SRAM_BASE, AT91SAM9G45_SRAM_SIZE);
-}
-
-static void __init at91sam9g45_initialize(void)
-{
- arm_pm_idle = at91sam9_idle;
-
- at91_sysirq_mask_rtc(AT91SAM9G45_BASE_RTC);
- at91_sysirq_mask_rtt(AT91SAM9G45_BASE_RTT);
-}
-
-AT91_SOC_START(at91sam9g45)
- .map_io = at91sam9g45_map_io,
- .init = at91sam9g45_initialize,
-AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9n12.c b/arch/arm/mach-at91/at91sam9n12.c
deleted file mode 100644
index dee569b1987e..000000000000
--- a/arch/arm/mach-at91/at91sam9n12.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * SoC specific setup code for the AT91SAM9N12
- *
- * Copyright (C) 2012 Atmel Corporation.
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <asm/system_misc.h>
-#include <mach/hardware.h>
-
-#include "soc.h"
-#include "generic.h"
-
-/* --------------------------------------------------------------------
- * AT91SAM9N12 processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init at91sam9n12_map_io(void)
-{
- at91_init_sram(0, AT91SAM9N12_SRAM_BASE, AT91SAM9N12_SRAM_SIZE);
-}
-
-static void __init at91sam9n12_initialize(void)
-{
- at91_sysirq_mask_rtc(AT91SAM9N12_BASE_RTC);
-}
-
-AT91_SOC_START(at91sam9n12)
- .map_io = at91sam9n12_map_io,
- .init = at91sam9n12_initialize,
-AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9rl.c b/arch/arm/mach-at91/at91sam9rl.c
deleted file mode 100644
index f25b9aec9c50..000000000000
--- a/arch/arm/mach-at91/at91sam9rl.c
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * arch/arm/mach-at91/at91sam9rl.c
- *
- * Copyright (C) 2005 SAN People
- * Copyright (C) 2007 Atmel Corporation
- *
- * 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 <asm/system_misc.h>
-#include <asm/irq.h>
-#include <mach/cpu.h>
-#include <mach/at91_dbgu.h>
-#include <mach/hardware.h>
-
-#include "soc.h"
-#include "generic.h"
-
-/* --------------------------------------------------------------------
- * AT91SAM9RL processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init at91sam9rl_map_io(void)
-{
- unsigned long sram_size;
-
- switch (at91_soc_initdata.cidr & AT91_CIDR_SRAMSIZ) {
- case AT91_CIDR_SRAMSIZ_32K:
- sram_size = 2 * SZ_16K;
- break;
- case AT91_CIDR_SRAMSIZ_16K:
- default:
- sram_size = SZ_16K;
- }
-
- /* Map SRAM */
- at91_init_sram(0, AT91SAM9RL_SRAM_BASE, sram_size);
-}
-
-static void __init at91sam9rl_initialize(void)
-{
- arm_pm_idle = at91sam9_idle;
-
- at91_sysirq_mask_rtc(AT91SAM9RL_BASE_RTC);
- at91_sysirq_mask_rtt(AT91SAM9RL_BASE_RTT);
-}
-
-AT91_SOC_START(at91sam9rl)
- .map_io = at91sam9rl_map_io,
- .init = at91sam9rl_initialize,
-AT91_SOC_END
diff --git a/arch/arm/mach-at91/at91sam9x5.c b/arch/arm/mach-at91/at91sam9x5.c
deleted file mode 100644
index f0d5a69a7237..000000000000
--- a/arch/arm/mach-at91/at91sam9x5.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Chip-specific setup code for the AT91SAM9x5 family
- *
- * Copyright (C) 2010-2012 Atmel Corporation.
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <asm/system_misc.h>
-#include <mach/hardware.h>
-
-#include "soc.h"
-#include "generic.h"
-
-/* --------------------------------------------------------------------
- * AT91SAM9x5 processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init at91sam9x5_map_io(void)
-{
- at91_init_sram(0, AT91SAM9X5_SRAM_BASE, AT91SAM9X5_SRAM_SIZE);
-}
-
-static void __init at91sam9x5_initialize(void)
-{
- at91_sysirq_mask_rtc(AT91SAM9X5_BASE_RTC);
-}
-
-/* --------------------------------------------------------------------
- * Interrupt initialization
- * -------------------------------------------------------------------- */
-
-AT91_SOC_START(at91sam9x5)
- .map_io = at91sam9x5_map_io,
- .init = at91sam9x5_initialize,
-AT91_SOC_END
diff --git a/arch/arm/mach-at91/board-dt-rm9200.c b/arch/arm/mach-at91/board-dt-rm9200.c
deleted file mode 100644
index 76dfe8f9af50..000000000000
--- a/arch/arm/mach-at91/board-dt-rm9200.c
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Setup code for AT91RM9200 Evaluation Kits with Device Tree support
- *
- * Copyright (C) 2011 Atmel,
- * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
- * 2012 Joachim Eastwood <manabian@gmail.com>
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/gpio.h>
-#include <linux/of.h>
-#include <linux/of_irq.h>
-#include <linux/clk-provider.h>
-
-#include <asm/setup.h>
-#include <asm/irq.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include "generic.h"
-
-static void __init at91rm9200_dt_timer_init(void)
-{
- of_clk_init(NULL);
- at91rm9200_timer_init();
-}
-
-static const char *at91rm9200_dt_board_compat[] __initdata = {
- "atmel,at91rm9200",
- NULL
-};
-
-DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)")
- .init_time = at91rm9200_dt_timer_init,
- .map_io = at91_map_io,
- .init_early = at91rm9200_dt_initialize,
- .dt_compat = at91rm9200_dt_board_compat,
-MACHINE_END
diff --git a/arch/arm/mach-at91/board-dt-sam9.c b/arch/arm/mach-at91/board-dt-sam9.c
deleted file mode 100644
index f99246aa9b38..000000000000
--- a/arch/arm/mach-at91/board-dt-sam9.c
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Setup code for AT91SAM Evaluation Kits with Device Tree support
- *
- * Copyright (C) 2011 Atmel,
- * 2011 Nicolas Ferre <nicolas.ferre@atmel.com>
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/gpio.h>
-#include <linux/of.h>
-#include <linux/of_irq.h>
-#include <linux/clk-provider.h>
-
-#include <asm/setup.h>
-#include <asm/irq.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include "generic.h"
-
-static const char *at91_dt_board_compat[] __initdata = {
- "atmel,at91sam9",
- NULL
-};
-
-DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)")
- /* Maintainer: Atmel */
- .map_io = at91_map_io,
- .init_early = at91_dt_initialize,
- .dt_compat = at91_dt_board_compat,
-MACHINE_END
diff --git a/arch/arm/mach-at91/board-dt-sama5.c b/arch/arm/mach-at91/board-dt-sama5.c
deleted file mode 100644
index 8fb9ef5333f1..000000000000
--- a/arch/arm/mach-at91/board-dt-sama5.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Setup code for SAMA5 Evaluation Kits with Device Tree support
- *
- * Copyright (C) 2013 Atmel,
- * 2013 Ludovic Desroches <ludovic.desroches@atmel.com>
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <linux/types.h>
-#include <linux/init.h>
-#include <linux/module.h>
-#include <linux/gpio.h>
-#include <linux/micrel_phy.h>
-#include <linux/of.h>
-#include <linux/of_irq.h>
-#include <linux/of_platform.h>
-#include <linux/phy.h>
-#include <linux/clk-provider.h>
-
-#include <asm/setup.h>
-#include <asm/irq.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <asm/mach/irq.h>
-
-#include "generic.h"
-
-static void __init sama5_dt_device_init(void)
-{
- of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
-}
-
-static const char *sama5_dt_board_compat[] __initconst = {
- "atmel,sama5",
- NULL
-};
-
-DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)")
- /* Maintainer: Atmel */
- .map_io = at91_map_io,
- .init_early = at91_dt_initialize,
- .init_machine = sama5_dt_device_init,
- .dt_compat = sama5_dt_board_compat,
-MACHINE_END
-
-static const char *sama5_alt_dt_board_compat[] __initconst = {
- "atmel,sama5d4",
- NULL
-};
-
-DT_MACHINE_START(sama5_alt_dt, "Atmel SAMA5 (Device Tree)")
- /* Maintainer: Atmel */
- .map_io = at91_alt_map_io,
- .init_early = at91_dt_initialize,
- .init_machine = sama5_dt_device_init,
- .dt_compat = sama5_alt_dt_board_compat,
- .l2c_aux_mask = ~0UL,
-MACHINE_END
diff --git a/arch/arm/mach-at91/generic.h b/arch/arm/mach-at91/generic.h
index d53324210adf..a6e726a6e0b5 100644
--- a/arch/arm/mach-at91/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -17,24 +17,28 @@
/* Map io */
extern void __init at91_map_io(void);
extern void __init at91_alt_map_io(void);
-extern void __init at91_init_sram(int bank, unsigned long base,
- unsigned int length);
-
- /* Processors */
-extern void __init at91rm9200_set_type(int type);
-extern void __init at91rm9200_dt_initialize(void);
-extern void __init at91_dt_initialize(void);
-
- /* Interrupts */
-extern void __init at91_sysirq_mask_rtc(u32 rtc_base);
-extern void __init at91_sysirq_mask_rtt(u32 rtt_base);
/* Timer */
extern void at91rm9200_timer_init(void);
/* idle */
+extern void at91rm9200_idle(void);
extern void at91sam9_idle(void);
/* Matrix */
extern void at91_ioremap_matrix(u32 base_addr);
+
+
+#ifdef CONFIG_PM
+extern void __init at91rm9200_pm_init(void);
+extern void __init at91sam9260_pm_init(void);
+extern void __init at91sam9g45_pm_init(void);
+extern void __init at91sam9x5_pm_init(void);
+#else
+void __init at91rm9200_pm_init(void) { }
+void __init at91sam9260_pm_init(void) { }
+void __init at91sam9g45_pm_init(void) { }
+void __init at91sam9x5_pm_init(void) { }
+#endif
+
#endif /* _AT91_GENERIC_H */
diff --git a/arch/arm/mach-at91/include/mach/at91_pio.h b/arch/arm/mach-at91/include/mach/at91_pio.h
deleted file mode 100644
index 7b7366253ceb..000000000000
--- a/arch/arm/mach-at91/include/mach/at91_pio.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/at91_pio.h
- *
- * Copyright (C) 2005 Ivan Kokshaysky
- * Copyright (C) SAN People
- *
- * Parallel I/O Controller (PIO) - System peripherals registers.
- * Based on AT91RM9200 datasheet revision E.
- *
- * This program is free software; you can redistribute it 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 AT91_PIO_H
-#define AT91_PIO_H
-
-#define PIO_PER 0x00 /* Enable Register */
-#define PIO_PDR 0x04 /* Disable Register */
-#define PIO_PSR 0x08 /* Status Register */
-#define PIO_OER 0x10 /* Output Enable Register */
-#define PIO_ODR 0x14 /* Output Disable Register */
-#define PIO_OSR 0x18 /* Output Status Register */
-#define PIO_IFER 0x20 /* Glitch Input Filter Enable */
-#define PIO_IFDR 0x24 /* Glitch Input Filter Disable */
-#define PIO_IFSR 0x28 /* Glitch Input Filter Status */
-#define PIO_SODR 0x30 /* Set Output Data Register */
-#define PIO_CODR 0x34 /* Clear Output Data Register */
-#define PIO_ODSR 0x38 /* Output Data Status Register */
-#define PIO_PDSR 0x3c /* Pin Data Status Register */
-#define PIO_IER 0x40 /* Interrupt Enable Register */
-#define PIO_IDR 0x44 /* Interrupt Disable Register */
-#define PIO_IMR 0x48 /* Interrupt Mask Register */
-#define PIO_ISR 0x4c /* Interrupt Status Register */
-#define PIO_MDER 0x50 /* Multi-driver Enable Register */
-#define PIO_MDDR 0x54 /* Multi-driver Disable Register */
-#define PIO_MDSR 0x58 /* Multi-driver Status Register */
-#define PIO_PUDR 0x60 /* Pull-up Disable Register */
-#define PIO_PUER 0x64 /* Pull-up Enable Register */
-#define PIO_PUSR 0x68 /* Pull-up Status Register */
-#define PIO_ASR 0x70 /* Peripheral A Select Register */
-#define PIO_ABCDSR1 0x70 /* Peripheral ABCD Select Register 1 [some sam9 only] */
-#define PIO_BSR 0x74 /* Peripheral B Select Register */
-#define PIO_ABCDSR2 0x74 /* Peripheral ABCD Select Register 2 [some sam9 only] */
-#define PIO_ABSR 0x78 /* AB Status Register */
-#define PIO_IFSCDR 0x80 /* Input Filter Slow Clock Disable Register */
-#define PIO_IFSCER 0x84 /* Input Filter Slow Clock Enable Register */
-#define PIO_IFSCSR 0x88 /* Input Filter Slow Clock Status Register */
-#define PIO_SCDR 0x8c /* Slow Clock Divider Debouncing Register */
-#define PIO_SCDR_DIV (0x3fff << 0) /* Slow Clock Divider Mask */
-#define PIO_PPDDR 0x90 /* Pad Pull-down Disable Register */
-#define PIO_PPDER 0x94 /* Pad Pull-down Enable Register */
-#define PIO_PPDSR 0x98 /* Pad Pull-down Status Register */
-#define PIO_OWER 0xa0 /* Output Write Enable Register */
-#define PIO_OWDR 0xa4 /* Output Write Disable Register */
-#define PIO_OWSR 0xa8 /* Output Write Status Register */
-#define PIO_AIMER 0xb0 /* Additional Interrupt Modes Enable Register */
-#define PIO_AIMDR 0xb4 /* Additional Interrupt Modes Disable Register */
-#define PIO_AIMMR 0xb8 /* Additional Interrupt Modes Mask Register */
-#define PIO_ESR 0xc0 /* Edge Select Register */
-#define PIO_LSR 0xc4 /* Level Select Register */
-#define PIO_ELSR 0xc8 /* Edge/Level Status Register */
-#define PIO_FELLSR 0xd0 /* Falling Edge/Low Level Select Register */
-#define PIO_REHLSR 0xd4 /* Rising Edge/ High Level Select Register */
-#define PIO_FRLHSR 0xd8 /* Fall/Rise - Low/High Status Register */
-#define PIO_SCHMITT 0x100 /* Schmitt Trigger Register */
-
-#define ABCDSR_PERIPH_A 0x0
-#define ABCDSR_PERIPH_B 0x1
-#define ABCDSR_PERIPH_C 0x2
-#define ABCDSR_PERIPH_D 0x3
-
-#define SAMA5D3_PIO_DRIVER1 0x118 /*PIO Driver 1 register offset*/
-#define SAMA5D3_PIO_DRIVER2 0x11C /*PIO Driver 2 register offset*/
-
-#define AT91SAM9X5_PIO_DRIVER1 0x114 /*PIO Driver 1 register offset*/
-#define AT91SAM9X5_PIO_DRIVER2 0x118 /*PIO Driver 2 register offset*/
-
-#endif
diff --git a/arch/arm/mach-at91/include/mach/at91_rtt.h b/arch/arm/mach-at91/include/mach/at91_rtt.h
deleted file mode 100644
index 7ec75de8bbb6..000000000000
--- a/arch/arm/mach-at91/include/mach/at91_rtt.h
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/at91_rtt.h
- *
- * Copyright (C) 2007 Andrew Victor
- * Copyright (C) 2007 Atmel Corporation.
- *
- * Real-time Timer (RTT) - System peripherals regsters.
- * Based on AT91SAM9261 datasheet revision D.
- *
- * This program is free software; you can redistribute it 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 AT91_RTT_H
-#define AT91_RTT_H
-
-#define AT91_RTT_MR 0x00 /* Real-time Mode Register */
-#define AT91_RTT_RTPRES (0xffff << 0) /* Real-time Timer Prescaler Value */
-#define AT91_RTT_ALMIEN (1 << 16) /* Alarm Interrupt Enable */
-#define AT91_RTT_RTTINCIEN (1 << 17) /* Real Time Timer Increment Interrupt Enable */
-#define AT91_RTT_RTTRST (1 << 18) /* Real Time Timer Restart */
-
-#define AT91_RTT_AR 0x04 /* Real-time Alarm Register */
-#define AT91_RTT_ALMV (0xffffffff) /* Alarm Value */
-
-#define AT91_RTT_VR 0x08 /* Real-time Value Register */
-#define AT91_RTT_CRTV (0xffffffff) /* Current Real-time Value */
-
-#define AT91_RTT_SR 0x0c /* Real-time Status Register */
-#define AT91_RTT_ALMS (1 << 0) /* Real-time Alarm Status */
-#define AT91_RTT_RTTINC (1 << 1) /* Real-time Timer Increment */
-
-#endif
diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h
index 61914fb35f5d..ce7c80a44983 100644
--- a/arch/arm/mach-at91/include/mach/cpu.h
+++ b/arch/arm/mach-at91/include/mach/cpu.h
@@ -152,69 +152,45 @@ static inline int at91_soc_is_detected(void)
#define cpu_is_at91rm9200_pqfp() (0)
#endif
-#ifdef CONFIG_SOC_AT91SAM9260
+#ifdef CONFIG_SOC_AT91SAM9
#define cpu_is_at91sam9xe() (at91_soc_initdata.subtype == AT91_SOC_SAM9XE)
#define cpu_is_at91sam9260() (at91_soc_initdata.type == AT91_SOC_SAM9260)
#define cpu_is_at91sam9g20() (at91_soc_initdata.type == AT91_SOC_SAM9G20)
-#else
-#define cpu_is_at91sam9xe() (0)
-#define cpu_is_at91sam9260() (0)
-#define cpu_is_at91sam9g20() (0)
-#endif
-
-#ifdef CONFIG_SOC_AT91SAM9261
#define cpu_is_at91sam9261() (at91_soc_initdata.type == AT91_SOC_SAM9261)
#define cpu_is_at91sam9g10() (at91_soc_initdata.type == AT91_SOC_SAM9G10)
-#else
-#define cpu_is_at91sam9261() (0)
-#define cpu_is_at91sam9g10() (0)
-#endif
-
-#ifdef CONFIG_SOC_AT91SAM9263
#define cpu_is_at91sam9263() (at91_soc_initdata.type == AT91_SOC_SAM9263)
-#else
-#define cpu_is_at91sam9263() (0)
-#endif
-
-#ifdef CONFIG_SOC_AT91SAM9RL
#define cpu_is_at91sam9rl() (at91_soc_initdata.type == AT91_SOC_SAM9RL)
-#else
-#define cpu_is_at91sam9rl() (0)
-#endif
-
-#ifdef CONFIG_SOC_AT91SAM9G45
#define cpu_is_at91sam9g45() (at91_soc_initdata.type == AT91_SOC_SAM9G45)
#define cpu_is_at91sam9g45es() (at91_soc_initdata.subtype == AT91_SOC_SAM9G45ES)
#define cpu_is_at91sam9m10() (at91_soc_initdata.subtype == AT91_SOC_SAM9M10)
#define cpu_is_at91sam9g46() (at91_soc_initdata.subtype == AT91_SOC_SAM9G46)
#define cpu_is_at91sam9m11() (at91_soc_initdata.subtype == AT91_SOC_SAM9M11)
-#else
-#define cpu_is_at91sam9g45() (0)
-#define cpu_is_at91sam9g45es() (0)
-#define cpu_is_at91sam9m10() (0)
-#define cpu_is_at91sam9g46() (0)
-#define cpu_is_at91sam9m11() (0)
-#endif
-
-#ifdef CONFIG_SOC_AT91SAM9X5
#define cpu_is_at91sam9x5() (at91_soc_initdata.type == AT91_SOC_SAM9X5)
#define cpu_is_at91sam9g15() (at91_soc_initdata.subtype == AT91_SOC_SAM9G15)
#define cpu_is_at91sam9g35() (at91_soc_initdata.subtype == AT91_SOC_SAM9G35)
#define cpu_is_at91sam9x35() (at91_soc_initdata.subtype == AT91_SOC_SAM9X35)
#define cpu_is_at91sam9g25() (at91_soc_initdata.subtype == AT91_SOC_SAM9G25)
#define cpu_is_at91sam9x25() (at91_soc_initdata.subtype == AT91_SOC_SAM9X25)
+#define cpu_is_at91sam9n12() (at91_soc_initdata.type == AT91_SOC_SAM9N12)
#else
+#define cpu_is_at91sam9xe() (0)
+#define cpu_is_at91sam9260() (0)
+#define cpu_is_at91sam9g20() (0)
+#define cpu_is_at91sam9261() (0)
+#define cpu_is_at91sam9g10() (0)
+#define cpu_is_at91sam9263() (0)
+#define cpu_is_at91sam9rl() (0)
+#define cpu_is_at91sam9g45() (0)
+#define cpu_is_at91sam9g45es() (0)
+#define cpu_is_at91sam9m10() (0)
+#define cpu_is_at91sam9g46() (0)
+#define cpu_is_at91sam9m11() (0)
#define cpu_is_at91sam9x5() (0)
#define cpu_is_at91sam9g15() (0)
#define cpu_is_at91sam9g35() (0)
#define cpu_is_at91sam9x35() (0)
#define cpu_is_at91sam9g25() (0)
#define cpu_is_at91sam9x25() (0)
-#endif
-
-#ifdef CONFIG_SOC_AT91SAM9N12
-#define cpu_is_at91sam9n12() (at91_soc_initdata.type == AT91_SOC_SAM9N12)
-#else
#define cpu_is_at91sam9n12() (0)
#endif
diff --git a/arch/arm/mach-at91/include/mach/memory.h b/arch/arm/mach-at91/include/mach/memory.h
deleted file mode 100644
index 401c207f2f39..000000000000
--- a/arch/arm/mach-at91/include/mach/memory.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * arch/arm/mach-at91/include/mach/memory.h
- *
- * Copyright (C) 2004 SAN People
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-#ifndef __ASM_ARCH_MEMORY_H
-#define __ASM_ARCH_MEMORY_H
-
-#include <mach/hardware.h>
-
-#endif
diff --git a/arch/arm/mach-at91/include/mach/system_rev.h b/arch/arm/mach-at91/include/mach/system_rev.h
deleted file mode 100644
index ef79a9aafc08..000000000000
--- a/arch/arm/mach-at91/include/mach/system_rev.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
- *
- * Under GPLv2 only
- */
-
-#ifndef __ARCH_SYSTEM_REV_H__
-#define __ARCH_SYSTEM_REV_H__
-
-#include <asm/system_info.h>
-
-/*
- * board revision encoding
- * mach specific
- * the 16-31 bit are reserved for at91 generic information
- *
- * bit 31:
- * 0 => nand 8 bit
- * 1 => nand 16 bit
- */
-#define BOARD_HAVE_NAND_16BIT (1 << 31)
-static inline int board_have_nand_16bit(void)
-{
- return (system_rev & BOARD_HAVE_NAND_16BIT) ? 1 : 0;
-}
-
-#endif /* __ARCH_SYSTEM_REV_H__ */
diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c
index 9b15169a1c62..af8d8afc2e12 100644
--- a/arch/arm/mach-at91/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -14,9 +14,13 @@
#include <linux/suspend.h>
#include <linux/sched.h>
#include <linux/proc_fs.h>
+#include <linux/genalloc.h>
#include <linux/interrupt.h>
#include <linux/sysfs.h>
#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/clk/at91_pmc.h>
@@ -32,7 +36,13 @@
#include "generic.h"
#include "pm.h"
+static struct {
+ unsigned long uhp_udp_mask;
+ int memctrl;
+} at91_pm_data;
+
static void (*at91_pm_standby)(void);
+void __iomem *at91_ramc_base[2];
static int at91_pm_valid_state(suspend_state_t state)
{
@@ -71,17 +81,9 @@ static int at91_pm_verify_clocks(void)
scsr = at91_pmc_read(AT91_PMC_SCSR);
/* USB must not be using PLLB */
- if (cpu_is_at91rm9200()) {
- if ((scsr & (AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP)) != 0) {
- pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
- return 0;
- }
- } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()
- || cpu_is_at91sam9g20() || cpu_is_at91sam9g10()) {
- if ((scsr & (AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP)) != 0) {
- pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
- return 0;
- }
+ if ((scsr & at91_pm_data.uhp_udp_mask) != 0) {
+ pr_err("AT91: PM - Suspend-to-RAM with USB still active\n");
+ return 0;
}
/* PCK0..PCK3 must be disabled, or configured to use clk32k */
@@ -149,18 +151,13 @@ static int at91_pm_enter(suspend_state_t state)
* turning off the main oscillator; reverse on wakeup.
*/
if (slow_clock) {
- int memctrl = AT91_MEMCTRL_SDRAMC;
-
- if (cpu_is_at91rm9200())
- memctrl = AT91_MEMCTRL_MC;
- else if (cpu_is_at91sam9g45())
- memctrl = AT91_MEMCTRL_DDRSDR;
#ifdef CONFIG_AT91_SLOW_CLOCK
/* copy slow_clock handler to SRAM, and call it */
memcpy(slow_clock, at91_slow_clock, at91_slow_clock_sz);
#endif
slow_clock(at91_pmc_base, at91_ramc_base[0],
- at91_ramc_base[1], memctrl);
+ at91_ramc_base[1],
+ at91_pm_data.memctrl);
break;
} else {
pr_info("AT91: PM - no slow clock mode enabled ...\n");
@@ -229,23 +226,134 @@ void at91_pm_set_standby(void (*at91_standby)(void))
}
}
-static int __init at91_pm_init(void)
+static struct of_device_id ramc_ids[] = {
+ { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby },
+ { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby },
+ { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby },
+ { .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby },
+ { /*sentinel*/ }
+};
+
+static void at91_dt_ramc(void)
{
+ struct device_node *np;
+ const struct of_device_id *of_id;
+ int idx = 0;
+ const void *standby = NULL;
+
+ for_each_matching_node_and_match(np, ramc_ids, &of_id) {
+ at91_ramc_base[idx] = of_iomap(np, 0);
+ if (!at91_ramc_base[idx])
+ panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
+
+ if (!standby)
+ standby = of_id->data;
+
+ idx++;
+ }
+
+ if (!idx)
+ panic(pr_fmt("unable to find compatible ram controller node in dtb\n"));
+
+ if (!standby) {
+ pr_warn("ramc no standby function available\n");
+ return;
+ }
+
+ at91_pm_set_standby(standby);
+}
+
#ifdef CONFIG_AT91_SLOW_CLOCK
- slow_clock = (void *) (AT91_IO_VIRT_BASE - at91_slow_clock_sz);
+static void __init at91_pm_sram_init(void)
+{
+ struct gen_pool *sram_pool;
+ phys_addr_t sram_pbase;
+ unsigned long sram_base;
+ struct device_node *node;
+ struct platform_device *pdev;
+
+ node = of_find_compatible_node(NULL, NULL, "mmio-sram");
+ if (!node) {
+ pr_warn("%s: failed to find sram node!\n", __func__);
+ return;
+ }
+
+ pdev = of_find_device_by_node(node);
+ if (!pdev) {
+ pr_warn("%s: failed to find sram device!\n", __func__);
+ goto put_node;
+ }
+
+ sram_pool = dev_get_gen_pool(&pdev->dev);
+ if (!sram_pool) {
+ pr_warn("%s: sram pool unavailable!\n", __func__);
+ goto put_node;
+ }
+
+ sram_base = gen_pool_alloc(sram_pool, at91_slow_clock_sz);
+ if (!sram_base) {
+ pr_warn("%s: unable to alloc ocram!\n", __func__);
+ goto put_node;
+ }
+
+ sram_pbase = gen_pool_virt_to_phys(sram_pool, sram_base);
+ slow_clock = __arm_ioremap_exec(sram_pbase, at91_slow_clock_sz, false);
+
+put_node:
+ of_node_put(node);
+}
+#endif
+
+
+static void __init at91_pm_init(void)
+{
+#ifdef CONFIG_AT91_SLOW_CLOCK
+ at91_pm_sram_init();
#endif
pr_info("AT91: Power Management%s\n", (slow_clock ? " (with slow clock mode)" : ""));
- /* AT91RM9200 SDRAM low-power mode cannot be used with self-refresh. */
- if (cpu_is_at91rm9200())
- at91_ramc_write(0, AT91RM9200_SDRAMC_LPR, 0);
-
if (at91_cpuidle_device.dev.platform_data)
platform_device_register(&at91_cpuidle_device);
suspend_set_ops(&at91_pm_ops);
+}
- return 0;
+void __init at91rm9200_pm_init(void)
+{
+ at91_dt_ramc();
+
+ /*
+ * AT91RM9200 SDRAM low-power mode cannot be used with self-refresh.
+ */
+ at91_ramc_write(0, AT91RM9200_SDRAMC_LPR, 0);
+
+ at91_pm_data.uhp_udp_mask = AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP;
+ at91_pm_data.memctrl = AT91_MEMCTRL_MC;
+
+ at91_pm_init();
+}
+
+void __init at91sam9260_pm_init(void)
+{
+ at91_dt_ramc();
+ at91_pm_data.memctrl = AT91_MEMCTRL_SDRAMC;
+ at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
+ return at91_pm_init();
+}
+
+void __init at91sam9g45_pm_init(void)
+{
+ at91_dt_ramc();
+ at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP;
+ at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
+ return at91_pm_init();
+}
+
+void __init at91sam9x5_pm_init(void)
+{
+ at91_dt_ramc();
+ at91_pm_data.uhp_udp_mask = AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP;
+ at91_pm_data.memctrl = AT91_MEMCTRL_DDRSDR;
+ return at91_pm_init();
}
-arch_initcall(at91_pm_init);
diff --git a/arch/arm/mach-at91/pm_slowclock.S b/arch/arm/mach-at91/pm_slowclock.S
index 20018779bae7..556151e85ec4 100644
--- a/arch/arm/mach-at91/pm_slowclock.S
+++ b/arch/arm/mach-at91/pm_slowclock.S
@@ -17,15 +17,6 @@
#include <mach/hardware.h>
#include <mach/at91_ramc.h>
-
-#ifdef CONFIG_SOC_AT91SAM9263
-/*
- * FIXME either or both the SDRAM controllers (EB0, EB1) might be in use;
- * handle those cases both here and in the Suspend-To-RAM support.
- */
-#warning Assuming EB1 SDRAM controller is *NOT* used
-#endif
-
/*
* When SLOWDOWN_MASTER_CLOCK is defined we will also slow down the Master
* clock during suspend by adjusting its prescalar and divisor.
diff --git a/arch/arm/mach-at91/sama5.c b/arch/arm/mach-at91/sama5.c
new file mode 100644
index 000000000000..03dcb441f3d2
--- /dev/null
+++ b/arch/arm/mach-at91/sama5.c
@@ -0,0 +1,111 @@
+/*
+ * Setup code for SAMA5
+ *
+ * Copyright (C) 2013 Atmel,
+ * 2013 Ludovic Desroches <ludovic.desroches@atmel.com>
+ *
+ * Licensed under GPLv2 or later.
+ */
+
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/gpio.h>
+#include <linux/micrel_phy.h>
+#include <linux/of.h>
+#include <linux/of_irq.h>
+#include <linux/of_platform.h>
+#include <linux/phy.h>
+#include <linux/clk-provider.h>
+#include <linux/phy.h>
+
+#include <mach/hardware.h>
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/map.h>
+#include <asm/mach/irq.h>
+
+#include "generic.h"
+
+static int ksz8081_phy_fixup(struct phy_device *phy)
+{
+ int value;
+
+ value = phy_read(phy, 0x16);
+ value &= ~0x20;
+ phy_write(phy, 0x16, value);
+
+ return 0;
+}
+
+static void __init sama5_dt_device_init(void)
+{
+ if (of_machine_is_compatible("atmel,sama5d4ek") &&
+ IS_ENABLED(CONFIG_PHYLIB)) {
+ phy_register_fixup_for_id("fc028000.etherne:00",
+ ksz8081_phy_fixup);
+ }
+
+ of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
+ at91sam9x5_pm_init();
+}
+
+static const char *sama5_dt_board_compat[] __initconst = {
+ "atmel,sama5",
+ NULL
+};
+
+DT_MACHINE_START(sama5_dt, "Atmel SAMA5")
+ /* Maintainer: Atmel */
+ .map_io = at91_map_io,
+ .init_machine = sama5_dt_device_init,
+ .dt_compat = sama5_dt_board_compat,
+MACHINE_END
+
+static struct map_desc at91_io_desc[] __initdata = {
+ {
+ .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_MPDDRC),
+ .pfn = __phys_to_pfn(SAMA5D4_BASE_MPDDRC),
+ .length = SZ_512,
+ .type = MT_DEVICE,
+ },
+ {
+ .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_PMC),
+ .pfn = __phys_to_pfn(SAMA5D4_BASE_PMC),
+ .length = SZ_512,
+ .type = MT_DEVICE,
+ },
+ { /* On sama5d4, we use USART3 as serial console */
+ .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_USART3),
+ .pfn = __phys_to_pfn(SAMA5D4_BASE_USART3),
+ .length = SZ_256,
+ .type = MT_DEVICE,
+ },
+ { /* A bunch of peripheral with fine grained IO space */
+ .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_SYS2),
+ .pfn = __phys_to_pfn(SAMA5D4_BASE_SYS2),
+ .length = SZ_2K,
+ .type = MT_DEVICE,
+ },
+};
+
+static void __init sama5_alt_map_io(void)
+{
+ at91_alt_map_io();
+ iotable_init(at91_io_desc, ARRAY_SIZE(at91_io_desc));
+}
+
+static const char *sama5_alt_dt_board_compat[] __initconst = {
+ "atmel,sama5d4",
+ NULL
+};
+
+DT_MACHINE_START(sama5_alt_dt, "Atmel SAMA5")
+ /* Maintainer: Atmel */
+ .map_io = sama5_alt_map_io,
+ .init_machine = sama5_dt_device_init,
+ .dt_compat = sama5_alt_dt_board_compat,
+ .l2c_aux_mask = ~0UL,
+MACHINE_END
diff --git a/arch/arm/mach-at91/sama5d3.c b/arch/arm/mach-at91/sama5d3.c
deleted file mode 100644
index 3d775d08de08..000000000000
--- a/arch/arm/mach-at91/sama5d3.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*
- * Chip-specific setup code for the SAMA5D3 family
- *
- * Copyright (C) 2013 Atmel,
- * 2013 Ludovic Desroches <ludovic.desroches@atmel.com>
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <linux/clk/at91_pmc.h>
-
-#include <asm/irq.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <mach/sama5d3.h>
-#include <mach/cpu.h>
-
-#include "soc.h"
-#include "generic.h"
-#include "sam9_smc.h"
-
-/* --------------------------------------------------------------------
- * AT91SAM9x5 processor initialization
- * -------------------------------------------------------------------- */
-
-static void __init sama5d3_map_io(void)
-{
- at91_init_sram(0, SAMA5D3_SRAM_BASE, SAMA5D3_SRAM_SIZE);
-}
-
-static void __init sama5d3_initialize(void)
-{
- at91_sysirq_mask_rtc(SAMA5D3_BASE_RTC);
-}
-
-AT91_SOC_START(sama5d3)
- .map_io = sama5d3_map_io,
- .init = sama5d3_initialize,
-AT91_SOC_END
diff --git a/arch/arm/mach-at91/sama5d4.c b/arch/arm/mach-at91/sama5d4.c
deleted file mode 100644
index 7638509639f4..000000000000
--- a/arch/arm/mach-at91/sama5d4.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Chip-specific setup code for the SAMA5D4 family
- *
- * Copyright (C) 2013 Atmel Corporation,
- * Nicolas Ferre <nicolas.ferre@atmel.com>
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <linux/module.h>
-#include <linux/dma-mapping.h>
-#include <linux/clk/at91_pmc.h>
-
-#include <asm/irq.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-#include <mach/sama5d4.h>
-#include <mach/cpu.h>
-#include <mach/hardware.h>
-
-#include "soc.h"
-#include "generic.h"
-#include "sam9_smc.h"
-
-/* --------------------------------------------------------------------
- * Processor initialization
- * -------------------------------------------------------------------- */
-static struct map_desc at91_io_desc[] __initdata = {
- {
- .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_MPDDRC),
- .pfn = __phys_to_pfn(SAMA5D4_BASE_MPDDRC),
- .length = SZ_512,
- .type = MT_DEVICE,
- },
- {
- .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_PMC),
- .pfn = __phys_to_pfn(SAMA5D4_BASE_PMC),
- .length = SZ_512,
- .type = MT_DEVICE,
- },
- { /* On sama5d4, we use USART3 as serial console */
- .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_USART3),
- .pfn = __phys_to_pfn(SAMA5D4_BASE_USART3),
- .length = SZ_256,
- .type = MT_DEVICE,
- },
- { /* A bunch of peripheral with fine grained IO space */
- .virtual = (unsigned long)AT91_ALT_IO_P2V(SAMA5D4_BASE_SYS2),
- .pfn = __phys_to_pfn(SAMA5D4_BASE_SYS2),
- .length = SZ_2K,
- .type = MT_DEVICE,
- },
-};
-
-
-static void __init sama5d4_map_io(void)
-{
- iotable_init(at91_io_desc, ARRAY_SIZE(at91_io_desc));
- at91_init_sram(0, SAMA5D4_NS_SRAM_BASE, SAMA5D4_NS_SRAM_SIZE);
-}
-
-AT91_SOC_START(sama5d4)
- .map_io = sama5d4_map_io,
-AT91_SOC_END
diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c
index ce25e85720fb..4e58bc90ed21 100644
--- a/arch/arm/mach-at91/setup.c
+++ b/arch/arm/mach-at91/setup.c
@@ -22,49 +22,12 @@
#include <mach/cpu.h>
#include <mach/at91_dbgu.h>
-#include "soc.h"
#include "generic.h"
#include "pm.h"
-struct at91_init_soc __initdata at91_boot_soc;
-
struct at91_socinfo at91_soc_initdata;
EXPORT_SYMBOL(at91_soc_initdata);
-void __init at91rm9200_set_type(int type)
-{
- if (type == ARCH_REVISON_9200_PQFP)
- at91_soc_initdata.subtype = AT91_SOC_RM9200_PQFP;
- else
- at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
-
- pr_info("filled in soc subtype: %s\n",
- at91_get_soc_subtype(&at91_soc_initdata));
-}
-
-void __iomem *at91_ramc_base[2];
-EXPORT_SYMBOL_GPL(at91_ramc_base);
-
-static struct map_desc sram_desc[2] __initdata;
-
-void __init at91_init_sram(int bank, unsigned long base, unsigned int length)
-{
- struct map_desc *desc = &sram_desc[bank];
-
- desc->virtual = (unsigned long)AT91_IO_VIRT_BASE - length;
- if (bank > 0)
- desc->virtual -= sram_desc[bank - 1].length;
-
- desc->pfn = __phys_to_pfn(base);
- desc->length = length;
- desc->type = MT_MEMORY_RWX_NONCACHED;
-
- pr_info("sram at 0x%lx of 0x%x mapped at 0x%lx\n",
- base, length, desc->virtual);
-
- iotable_init(desc, 1);
-}
-
static struct map_desc at91_io_desc __initdata __maybe_unused = {
.virtual = (unsigned long)AT91_VA_BASE_SYS,
.pfn = __phys_to_pfn(AT91_BASE_SYS),
@@ -91,61 +54,51 @@ static void __init soc_detect(u32 dbgu_base)
at91_soc_initdata.type = AT91_SOC_RM9200;
if (at91_soc_initdata.subtype == AT91_SOC_SUBTYPE_UNKNOWN)
at91_soc_initdata.subtype = AT91_SOC_RM9200_BGA;
- at91_boot_soc = at91rm9200_soc;
break;
case ARCH_ID_AT91SAM9260:
at91_soc_initdata.type = AT91_SOC_SAM9260;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
- at91_boot_soc = at91sam9260_soc;
break;
case ARCH_ID_AT91SAM9261:
at91_soc_initdata.type = AT91_SOC_SAM9261;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
- at91_boot_soc = at91sam9261_soc;
break;
case ARCH_ID_AT91SAM9263:
at91_soc_initdata.type = AT91_SOC_SAM9263;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
- at91_boot_soc = at91sam9263_soc;
break;
case ARCH_ID_AT91SAM9G20:
at91_soc_initdata.type = AT91_SOC_SAM9G20;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
- at91_boot_soc = at91sam9260_soc;
break;
case ARCH_ID_AT91SAM9G45:
at91_soc_initdata.type = AT91_SOC_SAM9G45;
if (cidr == ARCH_ID_AT91SAM9G45ES)
at91_soc_initdata.subtype = AT91_SOC_SAM9G45ES;
- at91_boot_soc = at91sam9g45_soc;
break;
case ARCH_ID_AT91SAM9RL64:
at91_soc_initdata.type = AT91_SOC_SAM9RL;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
- at91_boot_soc = at91sam9rl_soc;
break;
case ARCH_ID_AT91SAM9X5:
at91_soc_initdata.type = AT91_SOC_SAM9X5;
- at91_boot_soc = at91sam9x5_soc;
break;
case ARCH_ID_AT91SAM9N12:
at91_soc_initdata.type = AT91_SOC_SAM9N12;
- at91_boot_soc = at91sam9n12_soc;
break;
case ARCH_ID_SAMA5:
at91_soc_initdata.exid = __raw_readl(AT91_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D3) {
at91_soc_initdata.type = AT91_SOC_SAMA5D3;
- at91_boot_soc = sama5d3_soc;
}
break;
}
@@ -154,13 +107,11 @@ static void __init soc_detect(u32 dbgu_base)
if ((socid & ~AT91_CIDR_EXT) == ARCH_ID_AT91SAM9G10) {
at91_soc_initdata.type = AT91_SOC_SAM9G10;
at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE;
- at91_boot_soc = at91sam9261_soc;
}
/* at91sam9xe */
else if ((cidr & AT91_CIDR_ARCH) == ARCH_FAMILY_AT91SAM9XE) {
at91_soc_initdata.type = AT91_SOC_SAM9260;
at91_soc_initdata.subtype = AT91_SOC_SAM9XE;
- at91_boot_soc = at91sam9260_soc;
}
if (!at91_soc_is_detected())
@@ -240,10 +191,8 @@ static void __init alt_soc_detect(u32 dbgu_base)
at91_soc_initdata.exid = __raw_readl(AT91_ALT_IO_P2V(dbgu_base) + AT91_DBGU_EXID);
if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D3) {
at91_soc_initdata.type = AT91_SOC_SAMA5D3;
- at91_boot_soc = sama5d3_soc;
} else if (at91_soc_initdata.exid & ARCH_EXID_SAMA5D4) {
at91_soc_initdata.type = AT91_SOC_SAMA5D4;
- at91_boot_soc = sama5d4_soc;
}
break;
}
@@ -349,12 +298,6 @@ void __init at91_map_io(void)
if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE)
pr_info("Detected soc subtype: %s\n",
at91_get_soc_subtype(&at91_soc_initdata));
-
- if (!at91_soc_is_enabled())
- panic(pr_fmt("Soc not enabled"));
-
- if (at91_boot_soc.map_io)
- at91_boot_soc.map_io();
}
void __init at91_alt_map_io(void)
@@ -374,12 +317,6 @@ void __init at91_alt_map_io(void)
if (at91_soc_initdata.subtype != AT91_SOC_SUBTYPE_NONE)
pr_info("AT91: Detected soc subtype: %s\n",
at91_get_soc_subtype(&at91_soc_initdata));
-
- if (!at91_soc_is_enabled())
- panic("AT91: Soc not enabled");
-
- if (at91_boot_soc.map_io)
- at91_boot_soc.map_io();
}
void __iomem *at91_matrix_base;
@@ -391,55 +328,3 @@ void __init at91_ioremap_matrix(u32 base_addr)
if (!at91_matrix_base)
panic(pr_fmt("Impossible to ioremap at91_matrix_base\n"));
}
-
-static struct of_device_id ramc_ids[] = {
- { .compatible = "atmel,at91rm9200-sdramc", .data = at91rm9200_standby },
- { .compatible = "atmel,at91sam9260-sdramc", .data = at91sam9_sdram_standby },
- { .compatible = "atmel,at91sam9g45-ddramc", .data = at91_ddr_standby },
- { .compatible = "atmel,sama5d3-ddramc", .data = at91_ddr_standby },
- { /*sentinel*/ }
-};
-
-static void at91_dt_ramc(void)
-{
- struct device_node *np;
- const struct of_device_id *of_id;
- int idx = 0;
- const void *standby = NULL;
-
- for_each_matching_node_and_match(np, ramc_ids, &of_id) {
- at91_ramc_base[idx] = of_iomap(np, 0);
- if (!at91_ramc_base[idx])
- panic(pr_fmt("unable to map ramc[%d] cpu registers\n"), idx);
-
- if (!standby)
- standby = of_id->data;
-
- idx++;
- }
-
- if (!idx)
- panic(pr_fmt("unable to find compatible ram controller node in dtb\n"));
-
- if (!standby) {
- pr_warn("ramc no standby function available\n");
- return;
- }
-
- at91_pm_set_standby(standby);
-}
-
-void __init at91rm9200_dt_initialize(void)
-{
- at91_dt_ramc();
-
- at91_boot_soc.init();
-}
-
-void __init at91_dt_initialize(void)
-{
- at91_dt_ramc();
-
- if (at91_boot_soc.init)
- at91_boot_soc.init();
-}
diff --git a/arch/arm/mach-at91/soc.h b/arch/arm/mach-at91/soc.h
deleted file mode 100644
index ae6c0b2f1146..000000000000
--- a/arch/arm/mach-at91/soc.h
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2011 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
- *
- * Under GPLv2
- */
-
-struct at91_init_soc {
- int builtin;
- void (*map_io)(void);
- void (*init)(void);
-};
-
-extern struct at91_init_soc at91_boot_soc;
-extern struct at91_init_soc at91rm9200_soc;
-extern struct at91_init_soc at91sam9260_soc;
-extern struct at91_init_soc at91sam9261_soc;
-extern struct at91_init_soc at91sam9263_soc;
-extern struct at91_init_soc at91sam9g45_soc;
-extern struct at91_init_soc at91sam9rl_soc;
-extern struct at91_init_soc at91sam9x5_soc;
-extern struct at91_init_soc at91sam9n12_soc;
-extern struct at91_init_soc sama5d3_soc;
-extern struct at91_init_soc sama5d4_soc;
-
-#define AT91_SOC_START(_name) \
-struct at91_init_soc __initdata _name##_soc \
- __used \
- = { \
- .builtin = 1, \
-
-#define AT91_SOC_END \
-};
-
-static inline int at91_soc_is_enabled(void)
-{
- return at91_boot_soc.builtin;
-}
-
-#if !defined(CONFIG_SOC_AT91RM9200)
-#define at91rm9200_soc at91_boot_soc
-#endif
-
-#if !defined(CONFIG_SOC_AT91SAM9260)
-#define at91sam9260_soc at91_boot_soc
-#endif
-
-#if !defined(CONFIG_SOC_AT91SAM9261)
-#define at91sam9261_soc at91_boot_soc
-#endif
-
-#if !defined(CONFIG_SOC_AT91SAM9263)
-#define at91sam9263_soc at91_boot_soc
-#endif
-
-#if !defined(CONFIG_SOC_AT91SAM9G45)
-#define at91sam9g45_soc at91_boot_soc
-#endif
-
-#if !defined(CONFIG_SOC_AT91SAM9RL)
-#define at91sam9rl_soc at91_boot_soc
-#endif
-
-#if !defined(CONFIG_SOC_AT91SAM9X5)
-#define at91sam9x5_soc at91_boot_soc
-#endif
-
-#if !defined(CONFIG_SOC_AT91SAM9N12)
-#define at91sam9n12_soc at91_boot_soc
-#endif
-
-#if !defined(CONFIG_SOC_SAMA5D3)
-#define sama5d3_soc at91_boot_soc
-#endif
-
-#if !defined(CONFIG_SOC_SAMA5D4)
-#define sama5d4_soc at91_boot_soc
-#endif
diff --git a/arch/arm/mach-at91/sysirq_mask.c b/arch/arm/mach-at91/sysirq_mask.c
deleted file mode 100644
index f8bc3511a8c8..000000000000
--- a/arch/arm/mach-at91/sysirq_mask.c
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * sysirq_mask.c - System-interrupt masking
- *
- * Copyright (C) 2013 Johan Hovold <jhovold@gmail.com>
- *
- * Functions to disable system interrupts from backup-powered peripherals.
- *
- * The RTC and RTT-peripherals are generally powered by backup power (VDDBU)
- * and are not reset on wake-up, user, watchdog or software reset. This means
- * that their interrupts may be enabled during early boot (e.g. after a user
- * reset).
- *
- * As the RTC and RTT share the system-interrupt line with the PIT, an
- * interrupt occurring before a handler has been installed would lead to the
- * system interrupt being disabled and prevent the system from booting.
- *
- * This program is free software; you can redistribute it 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 <mach/at91_rtt.h>
-
-#include "generic.h"
-
-#define AT91_RTC_IDR 0x24 /* Interrupt Disable Register */
-#define AT91_RTC_IMR 0x28 /* Interrupt Mask Register */
-#define AT91_RTC_IRQ_MASK 0x1f /* Available IRQs mask */
-
-void __init at91_sysirq_mask_rtc(u32 rtc_base)
-{
- void __iomem *base;
-
- base = ioremap(rtc_base, 64);
- if (!base)
- return;
-
- /*
- * sam9x5 SoCs have the following errata:
- * "RTC: Interrupt Mask Register cannot be used
- * Interrupt Mask Register read always returns 0."
- *
- * Hence we're not relying on IMR values to disable
- * interrupts.
- */
- writel_relaxed(AT91_RTC_IRQ_MASK, base + AT91_RTC_IDR);
- (void)readl_relaxed(base + AT91_RTC_IMR); /* flush */
-
- iounmap(base);
-}
-
-void __init at91_sysirq_mask_rtt(u32 rtt_base)
-{
- void __iomem *base;
- void __iomem *reg;
- u32 mode;
-
- base = ioremap(rtt_base, 16);
- if (!base)
- return;
-
- reg = base + AT91_RTT_MR;
-
- mode = readl_relaxed(reg);
- if (mode & (AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN)) {
- pr_info("AT91: Disabling rtt irq\n");
- mode &= ~(AT91_RTT_ALMIEN | AT91_RTT_RTTINCIEN);
- writel_relaxed(mode, reg);
- (void)readl_relaxed(reg); /* flush */
- }
-
- iounmap(base);
-}
diff --git a/arch/arm/mach-bcm/platsmp-brcmstb.c b/arch/arm/mach-bcm/platsmp-brcmstb.c
index 31c87a284a34..e209e6fc7caf 100644
--- a/arch/arm/mach-bcm/platsmp-brcmstb.c
+++ b/arch/arm/mach-bcm/platsmp-brcmstb.c
@@ -17,6 +17,7 @@
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/io.h>
+#include <linux/jiffies.h>
#include <linux/of_address.h>
#include <linux/of_platform.h>
#include <linux/printk.h>
@@ -94,10 +95,35 @@ static u32 pwr_ctrl_rd(u32 cpu)
return readl_relaxed(base);
}
-static void pwr_ctrl_wr(u32 cpu, u32 val)
+static void pwr_ctrl_set(unsigned int cpu, u32 val, u32 mask)
{
void __iomem *base = pwr_ctrl_get_base(cpu);
- writel(val, base);
+ writel((readl(base) & mask) | val, base);
+}
+
+static void pwr_ctrl_clr(unsigned int cpu, u32 val, u32 mask)
+{
+ void __iomem *base = pwr_ctrl_get_base(cpu);
+ writel((readl(base) & mask) & ~val, base);
+}
+
+#define POLL_TMOUT_MS 500
+static int pwr_ctrl_wait_tmout(unsigned int cpu, u32 set, u32 mask)
+{
+ const unsigned long timeo = jiffies + msecs_to_jiffies(POLL_TMOUT_MS);
+ u32 tmp;
+
+ do {
+ tmp = pwr_ctrl_rd(cpu) & mask;
+ if (!set == !tmp)
+ return 0;
+ } while (time_before(jiffies, timeo));
+
+ tmp = pwr_ctrl_rd(cpu) & mask;
+ if (!set == !tmp)
+ return 0;
+
+ return -ETIMEDOUT;
}
static void cpu_rst_cfg_set(u32 cpu, int set)
@@ -139,15 +165,22 @@ static void brcmstb_cpu_power_on(u32 cpu)
* The secondary cores power was cut, so we must go through
* power-on initialization.
*/
- u32 tmp;
+ pwr_ctrl_set(cpu, ZONE_MAN_ISO_CNTL_MASK, 0xffffff00);
+ pwr_ctrl_set(cpu, ZONE_MANUAL_CONTROL_MASK, -1);
+ pwr_ctrl_set(cpu, ZONE_RESERVED_1_MASK, -1);
- /* Request zone power up */
- pwr_ctrl_wr(cpu, ZONE_PWR_UP_REQ_MASK);
+ pwr_ctrl_set(cpu, ZONE_MAN_MEM_PWR_MASK, -1);
- /* Wait for the power up FSM to complete */
- do {
- tmp = pwr_ctrl_rd(cpu);
- } while (!(tmp & ZONE_PWR_ON_STATE_MASK));
+ if (pwr_ctrl_wait_tmout(cpu, 1, ZONE_MEM_PWR_STATE_MASK))
+ panic("ZONE_MEM_PWR_STATE_MASK set timeout");
+
+ pwr_ctrl_set(cpu, ZONE_MAN_CLKEN_MASK, -1);
+
+ if (pwr_ctrl_wait_tmout(cpu, 1, ZONE_DPG_PWR_STATE_MASK))
+ panic("ZONE_DPG_PWR_STATE_MASK set timeout");
+
+ pwr_ctrl_clr(cpu, ZONE_MAN_ISO_CNTL_MASK, -1);
+ pwr_ctrl_set(cpu, ZONE_MAN_RESET_CNTL_MASK, -1);
}
static int brcmstb_cpu_get_power_state(u32 cpu)
@@ -174,25 +207,33 @@ static void brcmstb_cpu_die(u32 cpu)
static int brcmstb_cpu_kill(u32 cpu)
{
- u32 tmp;
+ /*
+ * Ordinarily, the hardware forbids power-down of CPU0 (which is good
+ * because it is the boot CPU), but this is not true when using BPCM
+ * manual mode. Consequently, we must avoid turning off CPU0 here to
+ * ensure that TI2C master reset will work.
+ */
+ if (cpu == 0) {
+ pr_warn("SMP: refusing to power off CPU0\n");
+ return 1;
+ }
while (per_cpu_sw_state_rd(cpu))
;
- /* Program zone reset */
- pwr_ctrl_wr(cpu, ZONE_RESET_STATE_MASK | ZONE_BLK_RST_ASSERT_MASK |
- ZONE_PWR_DN_REQ_MASK);
+ pwr_ctrl_set(cpu, ZONE_MANUAL_CONTROL_MASK, -1);
+ pwr_ctrl_clr(cpu, ZONE_MAN_RESET_CNTL_MASK, -1);
+ pwr_ctrl_clr(cpu, ZONE_MAN_CLKEN_MASK, -1);
+ pwr_ctrl_set(cpu, ZONE_MAN_ISO_CNTL_MASK, -1);
+ pwr_ctrl_clr(cpu, ZONE_MAN_MEM_PWR_MASK, -1);
- /* Verify zone reset */
- tmp = pwr_ctrl_rd(cpu);
- if (!(tmp & ZONE_RESET_STATE_MASK))
- pr_err("%s: Zone reset bit for CPU %d not asserted!\n",
- __func__, cpu);
+ if (pwr_ctrl_wait_tmout(cpu, 0, ZONE_MEM_PWR_STATE_MASK))
+ panic("ZONE_MEM_PWR_STATE_MASK clear timeout");
- /* Wait for power down */
- do {
- tmp = pwr_ctrl_rd(cpu);
- } while (!(tmp & ZONE_PWR_OFF_STATE_MASK));
+ pwr_ctrl_clr(cpu, ZONE_RESERVED_1_MASK, -1);
+
+ if (pwr_ctrl_wait_tmout(cpu, 0, ZONE_DPG_PWR_STATE_MASK))
+ panic("ZONE_DPG_PWR_STATE_MASK clear timeout");
/* Flush pipeline before resetting CPU */
mb();
diff --git a/arch/arm/mach-cns3xxx/pcie.c b/arch/arm/mach-cns3xxx/pcie.c
index 45d6bd09e6ef..c622c306c390 100644
--- a/arch/arm/mach-cns3xxx/pcie.c
+++ b/arch/arm/mach-cns3xxx/pcie.c
@@ -30,18 +30,15 @@ struct cns3xxx_pcie {
unsigned int irqs[2];
struct resource res_io;
struct resource res_mem;
- struct hw_pci hw_pci;
-
+ int port;
bool linked;
};
-static struct cns3xxx_pcie cns3xxx_pcie[]; /* forward decl. */
-
static struct cns3xxx_pcie *sysdata_to_cnspci(void *sysdata)
{
struct pci_sys_data *root = sysdata;
- return &cns3xxx_pcie[root->domain];
+ return root->private_data;
}
static struct cns3xxx_pcie *pdev_to_cnspci(const struct pci_dev *dev)
@@ -54,8 +51,8 @@ static struct cns3xxx_pcie *pbus_to_cnspci(struct pci_bus *bus)
return sysdata_to_cnspci(bus->sysdata);
}
-static void __iomem *cns3xxx_pci_cfg_base(struct pci_bus *bus,
- unsigned int devfn, int where)
+static void __iomem *cns3xxx_pci_map_bus(struct pci_bus *bus,
+ unsigned int devfn, int where)
{
struct cns3xxx_pcie *cnspci = pbus_to_cnspci(bus);
int busno = bus->number;
@@ -91,55 +88,22 @@ static void __iomem *cns3xxx_pci_cfg_base(struct pci_bus *bus,
static int cns3xxx_pci_read_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 *val)
{
- u32 v;
- void __iomem *base;
+ int ret;
u32 mask = (0x1ull << (size * 8)) - 1;
int shift = (where % 4) * 8;
- base = cns3xxx_pci_cfg_base(bus, devfn, where);
- if (!base) {
- *val = 0xffffffff;
- return PCIBIOS_SUCCESSFUL;
- }
-
- v = __raw_readl(base);
+ ret = pci_generic_config_read32(bus, devfn, where, size, val);
- if (bus->number == 0 && devfn == 0 &&
- (where & 0xffc) == PCI_CLASS_REVISION) {
+ if (ret == PCIBIOS_SUCCESSFUL && !bus->number && !devfn &&
+ (where & 0xffc) == PCI_CLASS_REVISION)
/*
* RC's class is 0xb, but Linux PCI driver needs 0x604
* for a PCIe bridge. So we must fixup the class code
* to 0x604 here.
*/
- v &= 0xff;
- v |= 0x604 << 16;
- }
+ *val = ((((*val << shift) & 0xff) | (0x604 << 16)) >> shift) & mask;
- *val = (v >> shift) & mask;
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int cns3xxx_pci_write_config(struct pci_bus *bus, unsigned int devfn,
- int where, int size, u32 val)
-{
- u32 v;
- void __iomem *base;
- u32 mask = (0x1ull << (size * 8)) - 1;
- int shift = (where % 4) * 8;
-
- base = cns3xxx_pci_cfg_base(bus, devfn, where);
- if (!base)
- return PCIBIOS_SUCCESSFUL;
-
- v = __raw_readl(base);
-
- v &= ~(mask << shift);
- v |= (val & mask) << shift;
-
- __raw_writel(v, base);
-
- return PCIBIOS_SUCCESSFUL;
+ return ret;
}
static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys)
@@ -158,8 +122,9 @@ static int cns3xxx_pci_setup(int nr, struct pci_sys_data *sys)
}
static struct pci_ops cns3xxx_pcie_ops = {
+ .map_bus = cns3xxx_pci_map_bus,
.read = cns3xxx_pci_read_config,
- .write = cns3xxx_pci_write_config,
+ .write = pci_generic_config_write,
};
static int cns3xxx_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
@@ -192,13 +157,7 @@ static struct cns3xxx_pcie cns3xxx_pcie[] = {
.flags = IORESOURCE_MEM,
},
.irqs = { IRQ_CNS3XXX_PCIE0_RC, IRQ_CNS3XXX_PCIE0_DEVICE, },
- .hw_pci = {
- .domain = 0,
- .nr_controllers = 1,
- .ops = &cns3xxx_pcie_ops,
- .setup = cns3xxx_pci_setup,
- .map_irq = cns3xxx_pcie_map_irq,
- },
+ .port = 0,
},
[1] = {
.host_regs = (void __iomem *)CNS3XXX_PCIE1_HOST_BASE_VIRT,
@@ -217,19 +176,13 @@ static struct cns3xxx_pcie cns3xxx_pcie[] = {
.flags = IORESOURCE_MEM,
},
.irqs = { IRQ_CNS3XXX_PCIE1_RC, IRQ_CNS3XXX_PCIE1_DEVICE, },
- .hw_pci = {
- .domain = 1,
- .nr_controllers = 1,
- .ops = &cns3xxx_pcie_ops,
- .setup = cns3xxx_pci_setup,
- .map_irq = cns3xxx_pcie_map_irq,
- },
+ .port = 1,
},
};
static void __init cns3xxx_pcie_check_link(struct cns3xxx_pcie *cnspci)
{
- int port = cnspci->hw_pci.domain;
+ int port = cnspci->port;
u32 reg;
unsigned long time;
@@ -260,9 +213,9 @@ static void __init cns3xxx_pcie_check_link(struct cns3xxx_pcie *cnspci)
static void __init cns3xxx_pcie_hw_init(struct cns3xxx_pcie *cnspci)
{
- int port = cnspci->hw_pci.domain;
+ int port = cnspci->port;
struct pci_sys_data sd = {
- .domain = port,
+ .private_data = cnspci,
};
struct pci_bus bus = {
.number = 0,
@@ -323,6 +276,14 @@ static int cns3xxx_pcie_abort_handler(unsigned long addr, unsigned int fsr,
void __init cns3xxx_pcie_init_late(void)
{
int i;
+ void *private_data;
+ struct hw_pci hw_pci = {
+ .nr_controllers = 1,
+ .ops = &cns3xxx_pcie_ops,
+ .setup = cns3xxx_pci_setup,
+ .map_irq = cns3xxx_pcie_map_irq,
+ .private_data = &private_data,
+ };
pcibios_min_io = 0;
pcibios_min_mem = 0;
@@ -335,7 +296,8 @@ void __init cns3xxx_pcie_init_late(void)
cns3xxx_pwr_soft_rst(0x1 << PM_SOFT_RST_REG_OFFST_PCIE(i));
cns3xxx_pcie_check_link(&cns3xxx_pcie[i]);
cns3xxx_pcie_hw_init(&cns3xxx_pcie[i]);
- pci_common_init(&cns3xxx_pcie[i].hw_pci);
+ private_data = &cns3xxx_pcie[i];
+ pci_common_init(&hw_pci);
}
pci_assign_unassigned_resources();
diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile
index 2204239ed243..2e3464b8bab4 100644
--- a/arch/arm/mach-davinci/Makefile
+++ b/arch/arm/mach-davinci/Makefile
@@ -27,7 +27,7 @@ obj-$(CONFIG_MACH_SFFSDR) += board-sffsdr.o
obj-$(CONFIG_MACH_NEUROS_OSD2) += board-neuros-osd2.o
obj-$(CONFIG_MACH_DAVINCI_DM355_EVM) += board-dm355-evm.o
obj-$(CONFIG_MACH_DM355_LEOPARD) += board-dm355-leopard.o
-obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o cdce949.o
+obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o
obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o
obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o
obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o
diff --git a/arch/arm/mach-davinci/board-dm646x-evm.c b/arch/arm/mach-davinci/board-dm646x-evm.c
index ae129bc49273..846a84ddc28e 100644
--- a/arch/arm/mach-davinci/board-dm646x-evm.c
+++ b/arch/arm/mach-davinci/board-dm646x-evm.c
@@ -45,7 +45,6 @@
#include <mach/irqs.h>
#include <mach/serial.h>
#include <mach/clock.h>
-#include <mach/cdce949.h>
#include "davinci.h"
#include "clock.h"
@@ -399,9 +398,6 @@ static struct i2c_board_info __initdata i2c_info[] = {
{
I2C_BOARD_INFO("cpld_video", 0x3b),
},
- {
- I2C_BOARD_INFO("cdce949", 0x6c),
- },
};
static struct davinci_i2c_platform_data i2c_pdata = {
@@ -715,31 +711,6 @@ static void __init evm_init_i2c(void)
evm_init_video();
}
-#define CDCE949_XIN_RATE 27000000
-
-/* CDCE949 support - "lpsc" field is overridden to work as clock number */
-static struct clk cdce_clk_in = {
- .name = "cdce_xin",
- .rate = CDCE949_XIN_RATE,
-};
-
-static struct clk_lookup cdce_clks[] = {
- CLK(NULL, "xin", &cdce_clk_in),
- CLK(NULL, NULL, NULL),
-};
-
-static void __init cdce_clk_init(void)
-{
- struct clk_lookup *c;
- struct clk *clk;
-
- for (c = cdce_clks; c->clk; c++) {
- clk = c->clk;
- clkdev_add(c);
- clk_register(clk);
- }
-}
-
#define DM6467T_EVM_REF_FREQ 33000000
static void __init davinci_map_io(void)
@@ -748,8 +719,6 @@ static void __init davinci_map_io(void)
if (machine_is_davinci_dm6467tevm())
davinci_set_refclk_rate(DM6467T_EVM_REF_FREQ);
-
- cdce_clk_init();
}
#define DM646X_EVM_PHY_ID "davinci_mdio-0:01"
diff --git a/arch/arm/mach-davinci/cdce949.c b/arch/arm/mach-davinci/cdce949.c
deleted file mode 100644
index abafb92031c0..000000000000
--- a/arch/arm/mach-davinci/cdce949.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*
- * TI CDCE949 clock synthesizer driver
- *
- * Note: This implementation assumes an input of 27MHz to the CDCE.
- * This is by no means constrained by CDCE hardware although the datasheet
- * does use this as an example for all illustrations and more importantly:
- * that is the crystal input on boards it is currently used on.
- *
- * Copyright (C) 2009 Texas Instruments Incorporated. http://www.ti.com/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- */
-#include <linux/kernel.h>
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/i2c.h>
-#include <linux/module.h>
-
-#include <mach/clock.h>
-#include <mach/cdce949.h>
-
-#include "clock.h"
-
-static struct i2c_client *cdce_i2c_client;
-static DEFINE_MUTEX(cdce_mutex);
-
-/* CDCE register descriptor */
-struct cdce_reg {
- u8 addr;
- u8 val;
-};
-
-/* Per-Output (Y1, Y2 etc.) frequency descriptor */
-struct cdce_freq {
- /* Frequency in KHz */
- unsigned long frequency;
- /*
- * List of registers to program to obtain a particular frequency.
- * 0x0 in register address and value is the end of list marker.
- */
- struct cdce_reg *reglist;
-};
-
-#define CDCE_FREQ_TABLE_ENTRY(line, out) \
-{ \
- .reglist = cdce_y ##line## _ ##out, \
- .frequency = out, \
-}
-
-/* List of CDCE outputs */
-struct cdce_output {
- /* List of frequencies on this output */
- struct cdce_freq *freq_table;
- /* Number of possible frequencies */
- int size;
-};
-
-/*
- * Finding out the values to program into CDCE949 registers for a particular
- * frequency output is not a simple calculation. Have a look at the datasheet
- * for the details. There is desktop software available to help users with
- * the calculations. Here, we just depend on the output of that software
- * (or hand calculations) instead trying to runtime calculate the register
- * values and inflicting misery on ourselves.
- */
-static struct cdce_reg cdce_y1_148500[] = {
- { 0x13, 0x00 },
- /* program PLL1_0 multiplier */
- { 0x18, 0xaf },
- { 0x19, 0x50 },
- { 0x1a, 0x02 },
- { 0x1b, 0xc9 },
- /* program PLL1_11 multiplier */
- { 0x1c, 0x00 },
- { 0x1d, 0x40 },
- { 0x1e, 0x02 },
- { 0x1f, 0xc9 },
- /* output state selection */
- { 0x15, 0x00 },
- { 0x14, 0xef },
- /* switch MUX to PLL1 output */
- { 0x14, 0x6f },
- { 0x16, 0x06 },
- /* set P2DIV divider, P3DIV and input crystal */
- { 0x17, 0x06 },
- { 0x01, 0x00 },
- { 0x05, 0x48 },
- { 0x02, 0x80 },
- /* enable and disable PLL */
- { 0x02, 0xbc },
- { 0x03, 0x01 },
- { },
-};
-
-static struct cdce_reg cdce_y1_74250[] = {
- { 0x13, 0x00 },
- { 0x18, 0xaf },
- { 0x19, 0x50 },
- { 0x1a, 0x02 },
- { 0x1b, 0xc9 },
- { 0x1c, 0x00 },
- { 0x1d, 0x40 },
- { 0x1e, 0x02 },
- { 0x1f, 0xc9 },
- /* output state selection */
- { 0x15, 0x00 },
- { 0x14, 0xef },
- /* switch MUX to PLL1 output */
- { 0x14, 0x6f },
- { 0x16, 0x06 },
- /* set P2DIV divider, P3DIV and input crystal */
- { 0x17, 0x06 },
- { 0x01, 0x00 },
- { 0x05, 0x48 },
- { 0x02, 0x80 },
- /* enable and disable PLL */
- { 0x02, 0xbc },
- { 0x03, 0x02 },
- { },
-};
-
-static struct cdce_reg cdce_y1_27000[] = {
- { 0x13, 0x00 },
- { 0x18, 0x00 },
- { 0x19, 0x40 },
- { 0x1a, 0x02 },
- { 0x1b, 0x08 },
- { 0x1c, 0x00 },
- { 0x1d, 0x40 },
- { 0x1e, 0x02 },
- { 0x1f, 0x08 },
- { 0x15, 0x02 },
- { 0x14, 0xed },
- { 0x16, 0x01 },
- { 0x17, 0x01 },
- { 0x01, 0x00 },
- { 0x05, 0x50 },
- { 0x02, 0xb4 },
- { 0x03, 0x01 },
- { },
-};
-
-static struct cdce_freq cdce_y1_freqs[] = {
- CDCE_FREQ_TABLE_ENTRY(1, 148500),
- CDCE_FREQ_TABLE_ENTRY(1, 74250),
- CDCE_FREQ_TABLE_ENTRY(1, 27000),
-};
-
-static struct cdce_reg cdce_y5_13500[] = {
- { 0x27, 0x08 },
- { 0x28, 0x00 },
- { 0x29, 0x40 },
- { 0x2a, 0x02 },
- { 0x2b, 0x08 },
- { 0x24, 0x6f },
- { },
-};
-
-static struct cdce_reg cdce_y5_16875[] = {
- { 0x27, 0x08 },
- { 0x28, 0x9f },
- { 0x29, 0xb0 },
- { 0x2a, 0x02 },
- { 0x2b, 0x89 },
- { 0x24, 0x6f },
- { },
-};
-
-static struct cdce_reg cdce_y5_27000[] = {
- { 0x27, 0x04 },
- { 0x28, 0x00 },
- { 0x29, 0x40 },
- { 0x2a, 0x02 },
- { 0x2b, 0x08 },
- { 0x24, 0x6f },
- { },
-};
-static struct cdce_reg cdce_y5_54000[] = {
- { 0x27, 0x04 },
- { 0x28, 0xff },
- { 0x29, 0x80 },
- { 0x2a, 0x02 },
- { 0x2b, 0x07 },
- { 0x24, 0x6f },
- { },
-};
-
-static struct cdce_reg cdce_y5_81000[] = {
- { 0x27, 0x02 },
- { 0x28, 0xbf },
- { 0x29, 0xa0 },
- { 0x2a, 0x03 },
- { 0x2b, 0x0a },
- { 0x24, 0x6f },
- { },
-};
-
-static struct cdce_freq cdce_y5_freqs[] = {
- CDCE_FREQ_TABLE_ENTRY(5, 13500),
- CDCE_FREQ_TABLE_ENTRY(5, 16875),
- CDCE_FREQ_TABLE_ENTRY(5, 27000),
- CDCE_FREQ_TABLE_ENTRY(5, 54000),
- CDCE_FREQ_TABLE_ENTRY(5, 81000),
-};
-
-
-static struct cdce_output output_list[] = {
- [1] = { cdce_y1_freqs, ARRAY_SIZE(cdce_y1_freqs) },
- [5] = { cdce_y5_freqs, ARRAY_SIZE(cdce_y5_freqs) },
-};
-
-int cdce_set_rate(struct clk *clk, unsigned long rate)
-{
- int i, ret = 0;
- struct cdce_freq *freq_table = output_list[clk->lpsc].freq_table;
- struct cdce_reg *regs = NULL;
-
- if (!cdce_i2c_client)
- return -ENODEV;
-
- if (!freq_table)
- return -EINVAL;
-
- for (i = 0; i < output_list[clk->lpsc].size; i++) {
- if (freq_table[i].frequency == rate / 1000) {
- regs = freq_table[i].reglist;
- break;
- }
- }
-
- if (!regs)
- return -EINVAL;
-
- mutex_lock(&cdce_mutex);
- for (i = 0; regs[i].addr; i++) {
- ret = i2c_smbus_write_byte_data(cdce_i2c_client,
- regs[i].addr | 0x80, regs[i].val);
- if (ret)
- break;
- }
- mutex_unlock(&cdce_mutex);
-
- if (!ret)
- clk->rate = rate;
-
- return ret;
-}
-
-static int cdce_probe(struct i2c_client *client,
- const struct i2c_device_id *id)
-{
- cdce_i2c_client = client;
- return 0;
-}
-
-static int cdce_remove(struct i2c_client *client)
-{
- cdce_i2c_client = NULL;
- return 0;
-}
-
-static const struct i2c_device_id cdce_id[] = {
- {"cdce949", 0},
- {},
-};
-MODULE_DEVICE_TABLE(i2c, cdce_id);
-
-static struct i2c_driver cdce_driver = {
- .driver = {
- .owner = THIS_MODULE,
- .name = "cdce949",
- },
- .probe = cdce_probe,
- .remove = cdce_remove,
- .id_table = cdce_id,
-};
-
-static int __init cdce_init(void)
-{
- return i2c_add_driver(&cdce_driver);
-}
-subsys_initcall(cdce_init);
-
-static void __exit cdce_exit(void)
-{
- i2c_del_driver(&cdce_driver);
-}
-module_exit(cdce_exit);
-
-MODULE_AUTHOR("Texas Instruments");
-MODULE_DESCRIPTION("CDCE949 clock synthesizer driver");
-MODULE_LICENSE("GPL v2");
diff --git a/arch/arm/mach-davinci/include/mach/cdce949.h b/arch/arm/mach-davinci/include/mach/cdce949.h
deleted file mode 100644
index c73331fae341..000000000000
--- a/arch/arm/mach-davinci/include/mach/cdce949.h
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * TI CDCE949 off-chip clock synthesizer support
- *
- * 2009 (C) Texas Instruments, Inc. http://www.ti.com/
- *
- * This file is licensed under the terms of the GNU General Public License
- * version 2. This program is licensed "as is" without any warranty of any
- * kind, whether express or implied.
- */
-#ifndef _MACH_DAVINCI_CDCE949_H
-#define _MACH_DAVINCI_CDCE949_H
-
-#include <linux/clk.h>
-
-#include <mach/clock.h>
-
-int cdce_set_rate(struct clk *clk, unsigned long rate);
-
-#endif
diff --git a/arch/arm/mach-davinci/serial.c b/arch/arm/mach-davinci/serial.c
index 5e93a734c858..951b620bfa73 100644
--- a/arch/arm/mach-davinci/serial.c
+++ b/arch/arm/mach-davinci/serial.c
@@ -31,16 +31,6 @@
#include <mach/serial.h>
#include <mach/cputype.h>
-static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
- int offset)
-{
- offset <<= up->regshift;
-
- WARN_ONCE(!up->membase, "unmapped read: uart[%d]\n", offset);
-
- return (unsigned int)__raw_readl(up->membase + offset);
-}
-
static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
int value)
{
diff --git a/arch/arm/mach-digicolor/Kconfig b/arch/arm/mach-digicolor/Kconfig
new file mode 100644
index 000000000000..4f36d8d2bc57
--- /dev/null
+++ b/arch/arm/mach-digicolor/Kconfig
@@ -0,0 +1,7 @@
+config ARCH_DIGICOLOR
+ bool "Conexant Digicolor SoC Support"
+ depends on ARCH_MULTI_V7
+ select CLKSRC_MMIO
+ select DIGICOLOR_TIMER
+ select GENERIC_IRQ_CHIP
+ select MFD_SYSCON
diff --git a/arch/arm/mach-digicolor/Makefile b/arch/arm/mach-digicolor/Makefile
new file mode 100644
index 000000000000..3d8a1d228408
--- /dev/null
+++ b/arch/arm/mach-digicolor/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_ARCH_DIGICOLOR) += digicolor.o
diff --git a/arch/arm/mach-digicolor/digicolor.c b/arch/arm/mach-digicolor/digicolor.c
new file mode 100644
index 000000000000..cfc88d1caa47
--- /dev/null
+++ b/arch/arm/mach-digicolor/digicolor.c
@@ -0,0 +1,18 @@
+/*
+ * Support for Conexant Digicolor SoCs
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <asm/mach/arch.h>
+
+static const char *digicolor_dt_compat[] __initconst = {
+ "cnxt,cx92755",
+ NULL,
+};
+
+DT_MACHINE_START(DIGICOLOR, "Conexant Digicolor (Flattened Device Tree)")
+ .dt_compat = digicolor_dt_compat,
+MACHINE_END
diff --git a/arch/arm/mach-exynos/exynos.c b/arch/arm/mach-exynos/exynos.c
index c13d0837fa8c..78eca99b98d1 100644
--- a/arch/arm/mach-exynos/exynos.c
+++ b/arch/arm/mach-exynos/exynos.c
@@ -27,20 +27,16 @@
#include <asm/mach/map.h>
#include <asm/memory.h>
+#include <mach/map.h>
+
#include "common.h"
#include "mfc.h"
#include "regs-pmu.h"
-#include "regs-sys.h"
void __iomem *pmu_base_addr;
static struct map_desc exynos4_iodesc[] __initdata = {
{
- .virtual = (unsigned long)S3C_VA_SYS,
- .pfn = __phys_to_pfn(EXYNOS4_PA_SYSCON),
- .length = SZ_64K,
- .type = MT_DEVICE,
- }, {
.virtual = (unsigned long)S5P_VA_SROMC,
.pfn = __phys_to_pfn(EXYNOS4_PA_SROMC),
.length = SZ_4K,
@@ -70,11 +66,6 @@ static struct map_desc exynos4_iodesc[] __initdata = {
static struct map_desc exynos5_iodesc[] __initdata = {
{
- .virtual = (unsigned long)S3C_VA_SYS,
- .pfn = __phys_to_pfn(EXYNOS5_PA_SYSCON),
- .length = SZ_64K,
- .type = MT_DEVICE,
- }, {
.virtual = (unsigned long)S5P_VA_SROMC,
.pfn = __phys_to_pfn(EXYNOS5_PA_SROMC),
.length = SZ_4K,
@@ -213,32 +204,6 @@ static void __init exynos_init_irq(void)
static void __init exynos_dt_machine_init(void)
{
- struct device_node *i2c_np;
- const char *i2c_compat = "samsung,s3c2440-i2c";
- unsigned int tmp;
- int id;
-
- /*
- * Exynos5's legacy i2c controller and new high speed i2c
- * controller have muxed interrupt sources. By default the
- * interrupts for 4-channel HS-I2C controller are enabled.
- * If node for first four channels of legacy i2c controller
- * are available then re-configure the interrupts via the
- * system register.
- */
- if (soc_is_exynos5()) {
- for_each_compatible_node(i2c_np, NULL, i2c_compat) {
- if (of_device_is_available(i2c_np)) {
- id = of_alias_get_id(i2c_np, "i2c");
- if (id < 4) {
- tmp = readl(EXYNOS5_SYS_I2C_CFG);
- writel(tmp & ~(0x1 << id),
- EXYNOS5_SYS_I2C_CFG);
- }
- }
- }
- }
-
/*
* This is called from smp_prepare_cpus if we've built for SMP, but
* we still need to set it up for PM and firmware ops if not.
@@ -282,6 +247,7 @@ static void __init exynos_reserve(void)
"samsung,mfc-v5",
"samsung,mfc-v6",
"samsung,mfc-v7",
+ "samsung,mfc-v8",
};
for (i = 0; i < ARRAY_SIZE(mfc_mem); i++)
diff --git a/arch/arm/mach-exynos/firmware.c b/arch/arm/mach-exynos/firmware.c
index 766f57d2f029..4791a3cc00f9 100644
--- a/arch/arm/mach-exynos/firmware.c
+++ b/arch/arm/mach-exynos/firmware.c
@@ -17,6 +17,7 @@
#include <asm/cacheflush.h>
#include <asm/cputype.h>
#include <asm/firmware.h>
+#include <asm/hardware/cache-l2x0.h>
#include <asm/suspend.h>
#include <mach/map.h>
@@ -136,6 +137,43 @@ static const struct firmware_ops exynos_firmware_ops = {
.resume = IS_ENABLED(CONFIG_EXYNOS_CPU_SUSPEND) ? exynos_resume : NULL,
};
+static void exynos_l2_write_sec(unsigned long val, unsigned reg)
+{
+ static int l2cache_enabled;
+
+ switch (reg) {
+ case L2X0_CTRL:
+ if (val & L2X0_CTRL_EN) {
+ /*
+ * Before the cache can be enabled, due to firmware
+ * design, SMC_CMD_L2X0INVALL must be called.
+ */
+ if (!l2cache_enabled) {
+ exynos_smc(SMC_CMD_L2X0INVALL, 0, 0, 0);
+ l2cache_enabled = 1;
+ }
+ } else {
+ l2cache_enabled = 0;
+ }
+ exynos_smc(SMC_CMD_L2X0CTRL, val, 0, 0);
+ break;
+
+ case L2X0_DEBUG_CTRL:
+ exynos_smc(SMC_CMD_L2X0DEBUG, val, 0, 0);
+ break;
+
+ default:
+ WARN_ONCE(1, "%s: ignoring write to reg 0x%x\n", __func__, reg);
+ }
+}
+
+static void exynos_l2_configure(const struct l2x0_regs *regs)
+{
+ exynos_smc(SMC_CMD_L2X0SETUP1, regs->tag_latency, regs->data_latency,
+ regs->prefetch_ctrl);
+ exynos_smc(SMC_CMD_L2X0SETUP2, regs->pwr_ctrl, regs->aux_ctrl, 0);
+}
+
void __init exynos_firmware_init(void)
{
struct device_node *nd;
@@ -155,4 +193,16 @@ void __init exynos_firmware_init(void)
pr_info("Running under secure firmware.\n");
register_firmware_ops(&exynos_firmware_ops);
+
+ /*
+ * Exynos 4 SoCs (based on Cortex A9 and equipped with L2C-310),
+ * running under secure firmware, require certain registers of L2
+ * cache controller to be written in secure mode. Here .write_sec
+ * callback is provided to perform necessary SMC calls.
+ */
+ if (IS_ENABLED(CONFIG_CACHE_L2X0) &&
+ read_cpuid_part() == ARM_CPU_PART_CORTEX_A9) {
+ outer_cache.write_sec = exynos_l2_write_sec;
+ outer_cache.configure = exynos_l2_configure;
+ }
}
diff --git a/arch/arm/mach-exynos/include/mach/dma.h b/arch/arm/mach-exynos/include/mach/dma.h
deleted file mode 100644
index 201842a3769e..000000000000
--- a/arch/arm/mach-exynos/include/mach/dma.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- * Jaswinder Singh <jassi.brar@samsung.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef __MACH_DMA_H
-#define __MACH_DMA_H
-
-/* This platform uses the common DMA API driver for PL330 */
-#include <plat/dma-pl330.h>
-
-#endif /* __MACH_DMA_H */
diff --git a/arch/arm/mach-exynos/include/mach/map.h b/arch/arm/mach-exynos/include/mach/map.h
index 1ad3f496ef56..de3ae59e1cfb 100644
--- a/arch/arm/mach-exynos/include/mach/map.h
+++ b/arch/arm/mach-exynos/include/mach/map.h
@@ -24,9 +24,6 @@
#define EXYNOS_PA_CHIPID 0x10000000
-#define EXYNOS4_PA_SYSCON 0x10010000
-#define EXYNOS5_PA_SYSCON 0x10050100
-
#define EXYNOS4_PA_CMU 0x10030000
#define EXYNOS5_PA_CMU 0x10010000
diff --git a/arch/arm/mach-exynos/pm.c b/arch/arm/mach-exynos/pm.c
index 86f3ecd88f78..dfc8594e5b1f 100644
--- a/arch/arm/mach-exynos/pm.c
+++ b/arch/arm/mach-exynos/pm.c
@@ -23,12 +23,13 @@
#include <asm/smp_scu.h>
#include <asm/suspend.h>
+#include <mach/map.h>
+
#include <plat/pm-common.h>
#include "common.h"
#include "exynos-pmu.h"
#include "regs-pmu.h"
-#include "regs-sys.h"
static inline void __iomem *exynos_boot_vector_addr(void)
{
diff --git a/arch/arm/mach-exynos/regs-pmu.h b/arch/arm/mach-exynos/regs-pmu.h
index b5f4406fc1b5..eb461e1c325a 100644
--- a/arch/arm/mach-exynos/regs-pmu.h
+++ b/arch/arm/mach-exynos/regs-pmu.h
@@ -160,12 +160,14 @@
#define EXYNOS5_L2RSTDISABLE_VALUE BIT(3)
#define S5P_PAD_RET_MAUDIO_OPTION 0x3028
+#define S5P_PAD_RET_MMC2_OPTION 0x30c8
#define S5P_PAD_RET_GPIO_OPTION 0x3108
#define S5P_PAD_RET_UART_OPTION 0x3128
#define S5P_PAD_RET_MMCA_OPTION 0x3148
#define S5P_PAD_RET_MMCB_OPTION 0x3168
#define S5P_PAD_RET_EBIA_OPTION 0x3188
#define S5P_PAD_RET_EBIB_OPTION 0x31A8
+#define S5P_PAD_RET_SPI_OPTION 0x31c8
#define S5P_PS_HOLD_CONTROL 0x330C
#define S5P_PS_HOLD_EN (1 << 31)
@@ -326,6 +328,7 @@
(EXYNOS3_ARM_CORE0_OPTION + ((_nr) * 0x80))
#define EXYNOS3_ARM_COMMON_OPTION 0x2408
+#define EXYNOS3_ARM_L2_OPTION 0x2608
#define EXYNOS3_TOP_PWR_OPTION 0x2C48
#define EXYNOS3_CORE_TOP_PWR_OPTION 0x2CA8
#define EXYNOS3_XUSBXTI_DURATION 0x341C
diff --git a/arch/arm/mach-exynos/regs-sys.h b/arch/arm/mach-exynos/regs-sys.h
deleted file mode 100644
index 84332b0dd7a6..000000000000
--- a/arch/arm/mach-exynos/regs-sys.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * EXYNOS - system register definition
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_ARCH_REGS_SYS_H
-#define __ASM_ARCH_REGS_SYS_H __FILE__
-
-#include <mach/map.h>
-
-#define S5P_SYSREG(x) (S3C_VA_SYS + (x))
-
-/* For EXYNOS5 */
-#define EXYNOS5_SYS_I2C_CFG S5P_SYSREG(0x0234)
-
-#endif /* __ASM_ARCH_REGS_SYS_H */
diff --git a/arch/arm/mach-exynos/sleep.S b/arch/arm/mach-exynos/sleep.S
index e3c373082bbe..31d25834b9c4 100644
--- a/arch/arm/mach-exynos/sleep.S
+++ b/arch/arm/mach-exynos/sleep.S
@@ -16,6 +16,8 @@
*/
#include <linux/linkage.h>
+#include <asm/asm-offsets.h>
+#include <asm/hardware/cache-l2x0.h>
#include "smc.h"
#define CPU_MASK 0xff0ffff0
@@ -74,6 +76,45 @@ ENTRY(exynos_cpu_resume_ns)
mov r0, #SMC_CMD_C15RESUME
dsb
smc #0
+#ifdef CONFIG_CACHE_L2X0
+ adr r0, 1f
+ ldr r2, [r0]
+ add r0, r2, r0
+
+ /* Check that the address has been initialised. */
+ ldr r1, [r0, #L2X0_R_PHY_BASE]
+ teq r1, #0
+ beq skip_l2x0
+
+ /* Check if controller has been enabled. */
+ ldr r2, [r1, #L2X0_CTRL]
+ tst r2, #0x1
+ bne skip_l2x0
+
+ ldr r1, [r0, #L2X0_R_TAG_LATENCY]
+ ldr r2, [r0, #L2X0_R_DATA_LATENCY]
+ ldr r3, [r0, #L2X0_R_PREFETCH_CTRL]
+ mov r0, #SMC_CMD_L2X0SETUP1
+ smc #0
+
+ /* Reload saved regs pointer because smc corrupts registers. */
+ adr r0, 1f
+ ldr r2, [r0]
+ add r0, r2, r0
+
+ ldr r1, [r0, #L2X0_R_PWR_CTRL]
+ ldr r2, [r0, #L2X0_R_AUX_CTRL]
+ mov r0, #SMC_CMD_L2X0SETUP2
+ smc #0
+
+ mov r0, #SMC_CMD_L2X0INVALL
+ smc #0
+
+ mov r1, #1
+ mov r0, #SMC_CMD_L2X0CTRL
+ smc #0
+skip_l2x0:
+#endif /* CONFIG_CACHE_L2X0 */
skip_cp15:
b cpu_resume
ENDPROC(exynos_cpu_resume_ns)
@@ -83,3 +124,8 @@ cp15_save_diag:
.globl cp15_save_power
cp15_save_power:
.long 0 @ cp15 power control
+
+#ifdef CONFIG_CACHE_L2X0
+ .align
+1: .long l2x0_saved_regs - .
+#endif /* CONFIG_CACHE_L2X0 */
diff --git a/arch/arm/mach-exynos/suspend.c b/arch/arm/mach-exynos/suspend.c
index f8e7dcd17055..82e6b6fba23f 100644
--- a/arch/arm/mach-exynos/suspend.c
+++ b/arch/arm/mach-exynos/suspend.c
@@ -34,7 +34,6 @@
#include "common.h"
#include "regs-pmu.h"
-#include "regs-sys.h"
#include "exynos-pmu.h"
#define S5P_CHECK_SLEEP 0x00000BAD
@@ -53,10 +52,6 @@ struct exynos_wkup_irq {
u32 mask;
};
-static struct sleep_save exynos5_sys_save[] = {
- SAVE_ITEM(EXYNOS5_SYS_I2C_CFG),
-};
-
static struct sleep_save exynos_core_save[] = {
/* SROM side */
SAVE_ITEM(S5P_SROM_BW),
@@ -91,6 +86,12 @@ static unsigned int exynos_pmu_spare3;
static u32 exynos_irqwake_intmask = 0xffffffff;
+static const struct exynos_wkup_irq exynos3250_wkup_irq[] = {
+ { 73, BIT(1) }, /* RTC alarm */
+ { 74, BIT(2) }, /* RTC tick */
+ { /* sentinel */ },
+};
+
static const struct exynos_wkup_irq exynos4_wkup_irq[] = {
{ 76, BIT(1) }, /* RTC alarm */
{ 77, BIT(2) }, /* RTC tick */
@@ -114,6 +115,19 @@ unsigned int exynos_release_ret_regs[] = {
REG_TABLE_END,
};
+unsigned int exynos3250_release_ret_regs[] = {
+ S5P_PAD_RET_MAUDIO_OPTION,
+ S5P_PAD_RET_GPIO_OPTION,
+ S5P_PAD_RET_UART_OPTION,
+ S5P_PAD_RET_MMCA_OPTION,
+ S5P_PAD_RET_MMCB_OPTION,
+ S5P_PAD_RET_EBIA_OPTION,
+ S5P_PAD_RET_EBIB_OPTION,
+ S5P_PAD_RET_MMC2_OPTION,
+ S5P_PAD_RET_SPI_OPTION,
+ REG_TABLE_END,
+};
+
unsigned int exynos5420_release_ret_regs[] = {
EXYNOS_PAD_RET_DRAM_OPTION,
EXYNOS_PAD_RET_MAUDIO_OPTION,
@@ -173,6 +187,12 @@ static int exynos_cpu_suspend(unsigned long arg)
return exynos_cpu_do_idle();
}
+static int exynos3250_cpu_suspend(unsigned long arg)
+{
+ flush_cache_all();
+ return exynos_cpu_do_idle();
+}
+
static int exynos5420_cpu_suspend(unsigned long arg)
{
/* MCPM works with HW CPU identifiers */
@@ -230,6 +250,23 @@ static void exynos_pm_prepare(void)
pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
}
+static void exynos3250_pm_prepare(void)
+{
+ unsigned int tmp;
+
+ /* Set wake-up mask registers */
+ exynos_pm_set_wakeup_mask();
+
+ tmp = pmu_raw_readl(EXYNOS3_ARM_L2_OPTION);
+ tmp &= ~EXYNOS5_OPTION_USE_RETENTION;
+ pmu_raw_writel(tmp, EXYNOS3_ARM_L2_OPTION);
+
+ exynos_pm_enter_sleep_mode();
+
+ /* ensure at least INFORM0 has the resume address */
+ pmu_raw_writel(virt_to_phys(exynos_cpu_resume), S5P_INFORM0);
+}
+
static void exynos5420_pm_prepare(void)
{
unsigned int tmp;
@@ -344,6 +381,28 @@ early_wakeup:
pmu_raw_writel(0x0, S5P_INFORM1);
}
+static void exynos3250_pm_resume(void)
+{
+ u32 cpuid = read_cpuid_part();
+
+ if (exynos_pm_central_resume())
+ goto early_wakeup;
+
+ /* For release retention */
+ exynos_pm_release_retention();
+
+ pmu_raw_writel(S5P_USE_STANDBY_WFI_ALL, S5P_CENTRAL_SEQ_OPTION);
+
+ if (call_firmware_op(resume) == -ENOSYS
+ && cpuid == ARM_CPU_PART_CORTEX_A9)
+ exynos_cpu_restore_register();
+
+early_wakeup:
+
+ /* Clear SLEEP mode set in INFORM1 */
+ pmu_raw_writel(0x0, S5P_INFORM1);
+}
+
static void exynos5420_prepare_pm_resume(void)
{
if (IS_ENABLED(CONFIG_EXYNOS5420_MCPM))
@@ -483,6 +542,16 @@ static const struct platform_suspend_ops exynos_suspend_ops = {
.valid = suspend_valid_only_mem,
};
+static const struct exynos_pm_data exynos3250_pm_data = {
+ .wkup_irq = exynos3250_wkup_irq,
+ .wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
+ .release_ret_regs = exynos3250_release_ret_regs,
+ .pm_suspend = exynos_pm_suspend,
+ .pm_resume = exynos3250_pm_resume,
+ .pm_prepare = exynos3250_pm_prepare,
+ .cpu_suspend = exynos3250_cpu_suspend,
+};
+
static const struct exynos_pm_data exynos4_pm_data = {
.wkup_irq = exynos4_wkup_irq,
.wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
@@ -497,8 +566,6 @@ static const struct exynos_pm_data exynos5250_pm_data = {
.wkup_irq = exynos5250_wkup_irq,
.wake_disable_mask = ((0xFF << 8) | (0x1F << 1)),
.release_ret_regs = exynos_release_ret_regs,
- .extra_save = exynos5_sys_save,
- .num_extra_save = ARRAY_SIZE(exynos5_sys_save),
.pm_suspend = exynos_pm_suspend,
.pm_resume = exynos_pm_resume,
.pm_prepare = exynos_pm_prepare,
@@ -518,6 +585,9 @@ static struct exynos_pm_data exynos5420_pm_data = {
static struct of_device_id exynos_pmu_of_device_ids[] = {
{
+ .compatible = "samsung,exynos3250-pmu",
+ .data = &exynos3250_pm_data,
+ }, {
.compatible = "samsung,exynos4210-pmu",
.data = &exynos4_pm_data,
}, {
diff --git a/arch/arm/mach-hisi/Kconfig b/arch/arm/mach-hisi/Kconfig
index cd19433f76d3..83061ad0e282 100644
--- a/arch/arm/mach-hisi/Kconfig
+++ b/arch/arm/mach-hisi/Kconfig
@@ -22,6 +22,14 @@ config ARCH_HI3xxx
help
Support for Hisilicon Hi36xx SoC family
+config ARCH_HIP01
+ bool "Hisilicon HIP01 family" if ARCH_MULTI_V7
+ select HAVE_ARM_SCU if SMP
+ select HAVE_ARM_TWD if SMP
+ select ARM_GLOBAL_TIMER
+ help
+ Support for Hisilicon HIP01 SoC family
+
config ARCH_HIP04
bool "Hisilicon HiP04 Cortex A15 family" if ARCH_MULTI_V7
select ARM_ERRATA_798181 if SMP
diff --git a/arch/arm/mach-hisi/core.h b/arch/arm/mach-hisi/core.h
index 88b1f487d065..92a682d8e939 100644
--- a/arch/arm/mach-hisi/core.h
+++ b/arch/arm/mach-hisi/core.h
@@ -12,9 +12,12 @@ extern void hi3xxx_cpu_die(unsigned int cpu);
extern int hi3xxx_cpu_kill(unsigned int cpu);
extern void hi3xxx_set_cpu(int cpu, bool enable);
-extern void hix5hd2_secondary_startup(void);
+extern void hisi_secondary_startup(void);
extern struct smp_operations hix5hd2_smp_ops;
extern void hix5hd2_set_cpu(int cpu, bool enable);
extern void hix5hd2_cpu_die(unsigned int cpu);
+extern struct smp_operations hip01_smp_ops;
+extern void hip01_set_cpu(int cpu, bool enable);
+extern void hip01_cpu_die(unsigned int cpu);
#endif
diff --git a/arch/arm/mach-hisi/headsmp.S b/arch/arm/mach-hisi/headsmp.S
index 278889c00b77..81e35b159e75 100644
--- a/arch/arm/mach-hisi/headsmp.S
+++ b/arch/arm/mach-hisi/headsmp.S
@@ -11,6 +11,6 @@
__CPUINIT
-ENTRY(hix5hd2_secondary_startup)
+ENTRY(hisi_secondary_startup)
bl v7_invalidate_l1
b secondary_startup
diff --git a/arch/arm/mach-hisi/hisilicon.c b/arch/arm/mach-hisi/hisilicon.c
index 7744c351bbfd..76b907078b58 100644
--- a/arch/arm/mach-hisi/hisilicon.c
+++ b/arch/arm/mach-hisi/hisilicon.c
@@ -72,3 +72,13 @@ static const char *hip04_compat[] __initconst = {
DT_MACHINE_START(HIP04, "Hisilicon HiP04 (Flattened Device Tree)")
.dt_compat = hip04_compat,
MACHINE_END
+
+static const char *hip01_compat[] __initconst = {
+ "hisilicon,hip01",
+ "hisilicon,hip01-ca9x2",
+ NULL,
+};
+
+DT_MACHINE_START(HIP01, "Hisilicon HIP01 (Flattened Device Tree)")
+ .dt_compat = hip01_compat,
+MACHINE_END
diff --git a/arch/arm/mach-hisi/hotplug.c b/arch/arm/mach-hisi/hotplug.c
index 84e6919f68c7..a129aae72602 100644
--- a/arch/arm/mach-hisi/hotplug.c
+++ b/arch/arm/mach-hisi/hotplug.c
@@ -65,6 +65,9 @@
#define PMC0_CPU1_PMC_ENABLE (1 << 7)
#define PMC0_CPU1_POWERDOWN (1 << 3)
+#define HIP01_PERI9 0x50
+#define PERI9_CPU1_RESET (1 << 1)
+
enum {
HI3620_CTRL,
ERROR_CTRL,
@@ -209,6 +212,34 @@ void hix5hd2_set_cpu(int cpu, bool enable)
}
}
+void hip01_set_cpu(int cpu, bool enable)
+{
+ unsigned int temp;
+ struct device_node *np;
+
+ if (!ctrl_base) {
+ np = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl");
+ if (np)
+ ctrl_base = of_iomap(np, 0);
+ else
+ BUG();
+ }
+
+ if (enable) {
+ /* reset on CPU1 */
+ temp = readl_relaxed(ctrl_base + HIP01_PERI9);
+ temp |= PERI9_CPU1_RESET;
+ writel_relaxed(temp, ctrl_base + HIP01_PERI9);
+
+ udelay(50);
+
+ /* unreset on CPU1 */
+ temp = readl_relaxed(ctrl_base + HIP01_PERI9);
+ temp &= ~PERI9_CPU1_RESET;
+ writel_relaxed(temp, ctrl_base + HIP01_PERI9);
+ }
+}
+
static inline void cpu_enter_lowpower(void)
{
unsigned int v;
diff --git a/arch/arm/mach-hisi/platsmp.c b/arch/arm/mach-hisi/platsmp.c
index 575dd8285f1f..8880c8e8b296 100644
--- a/arch/arm/mach-hisi/platsmp.c
+++ b/arch/arm/mach-hisi/platsmp.c
@@ -10,10 +10,12 @@
#include <linux/smp.h>
#include <linux/io.h>
#include <linux/of_address.h>
+#include <linux/delay.h>
#include <asm/cacheflush.h>
#include <asm/smp_plat.h>
#include <asm/smp_scu.h>
+#include <asm/mach/map.h>
#include "core.h"
@@ -96,7 +98,7 @@ struct smp_operations hi3xxx_smp_ops __initdata = {
#endif
};
-static void __init hix5hd2_smp_prepare_cpus(unsigned int max_cpus)
+static void __init hisi_common_smp_prepare_cpus(unsigned int max_cpus)
{
hisi_enable_scu_a9();
}
@@ -116,7 +118,7 @@ static int hix5hd2_boot_secondary(unsigned int cpu, struct task_struct *idle)
{
phys_addr_t jumpaddr;
- jumpaddr = virt_to_phys(hix5hd2_secondary_startup);
+ jumpaddr = virt_to_phys(hisi_secondary_startup);
hix5hd2_set_scu_boot_addr(HIX5HD2_BOOT_ADDRESS, jumpaddr);
hix5hd2_set_cpu(cpu, true);
arch_send_wakeup_ipi_mask(cpumask_of(cpu));
@@ -125,12 +127,60 @@ static int hix5hd2_boot_secondary(unsigned int cpu, struct task_struct *idle)
struct smp_operations hix5hd2_smp_ops __initdata = {
- .smp_prepare_cpus = hix5hd2_smp_prepare_cpus,
+ .smp_prepare_cpus = hisi_common_smp_prepare_cpus,
.smp_boot_secondary = hix5hd2_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
.cpu_die = hix5hd2_cpu_die,
#endif
};
+
+#define SC_SCTL_REMAP_CLR 0x00000100
+#define HIP01_BOOT_ADDRESS 0x80000000
+#define REG_SC_CTRL 0x000
+
+void hip01_set_boot_addr(phys_addr_t start_addr, phys_addr_t jump_addr)
+{
+ void __iomem *virt;
+
+ virt = phys_to_virt(start_addr);
+
+ writel_relaxed(0xe51ff004, virt);
+ writel_relaxed(jump_addr, virt + 4);
+}
+
+static int hip01_boot_secondary(unsigned int cpu, struct task_struct *idle)
+{
+ phys_addr_t jumpaddr;
+ unsigned int remap_reg_value = 0;
+ struct device_node *node;
+
+
+ jumpaddr = virt_to_phys(hisi_secondary_startup);
+ hip01_set_boot_addr(HIP01_BOOT_ADDRESS, jumpaddr);
+
+ node = of_find_compatible_node(NULL, NULL, "hisilicon,hip01-sysctrl");
+ if (WARN_ON(!node))
+ return -1;
+ ctrl_base = of_iomap(node, 0);
+
+ /* set the secondary core boot from DDR */
+ remap_reg_value = readl_relaxed(ctrl_base + REG_SC_CTRL);
+ barrier();
+ remap_reg_value |= SC_SCTL_REMAP_CLR;
+ barrier();
+ writel_relaxed(remap_reg_value, ctrl_base + REG_SC_CTRL);
+
+ hip01_set_cpu(cpu, true);
+
+ return 0;
+}
+
+struct smp_operations hip01_smp_ops __initdata = {
+ .smp_prepare_cpus = hisi_common_smp_prepare_cpus,
+ .smp_boot_secondary = hip01_boot_secondary,
+};
+
CPU_METHOD_OF_DECLARE(hi3xxx_smp, "hisilicon,hi3620-smp", &hi3xxx_smp_ops);
CPU_METHOD_OF_DECLARE(hix5hd2_smp, "hisilicon,hix5hd2-smp", &hix5hd2_smp_ops);
+CPU_METHOD_OF_DECLARE(hip01_smp, "hisilicon,hip01-smp", &hip01_smp_ops);
diff --git a/arch/arm/mach-imx/clk-imx6q.c b/arch/arm/mach-imx/clk-imx6q.c
index 5951660d1bd2..d04a430607b8 100644
--- a/arch/arm/mach-imx/clk-imx6q.c
+++ b/arch/arm/mach-imx/clk-imx6q.c
@@ -144,7 +144,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
post_div_table[1].div = 1;
post_div_table[2].div = 1;
video_div_table[1].div = 1;
- video_div_table[2].div = 1;
+ video_div_table[3].div = 1;
}
clk[IMX6QDL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 2, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
@@ -386,7 +386,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk[IMX6Q_CLK_ECSPI5] = imx_clk_gate2("ecspi5", "ecspi_root", base + 0x6c, 8);
clk[IMX6QDL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10);
clk[IMX6QDL_CLK_ESAI_EXTAL] = imx_clk_gate2_shared("esai_extal", "esai_podf", base + 0x6c, 16, &share_count_esai);
- clk[IMX6QDL_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ipg", base + 0x6c, 16, &share_count_esai);
+ clk[IMX6QDL_CLK_ESAI_IPG] = imx_clk_gate2_shared("esai_ipg", "ahb", base + 0x6c, 16, &share_count_esai);
clk[IMX6QDL_CLK_ESAI_MEM] = imx_clk_gate2_shared("esai_mem", "ahb", base + 0x6c, 16, &share_count_esai);
clk[IMX6QDL_CLK_GPT_IPG] = imx_clk_gate2("gpt_ipg", "ipg", base + 0x6c, 20);
clk[IMX6QDL_CLK_GPT_IPG_PER] = imx_clk_gate2("gpt_ipg_per", "ipg_per", base + 0x6c, 22);
diff --git a/arch/arm/mach-imx/clk-imx6sx.c b/arch/arm/mach-imx/clk-imx6sx.c
index 17354a11356f..5a3e5a159e70 100644
--- a/arch/arm/mach-imx/clk-imx6sx.c
+++ b/arch/arm/mach-imx/clk-imx6sx.c
@@ -558,6 +558,9 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
clk_set_parent(clks[IMX6SX_CLK_GPU_CORE_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
clk_set_parent(clks[IMX6SX_CLK_GPU_AXI_SEL], clks[IMX6SX_CLK_PLL3_PFD0]);
+ clk_set_parent(clks[IMX6SX_CLK_QSPI1_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
+ clk_set_parent(clks[IMX6SX_CLK_QSPI2_SEL], clks[IMX6SX_CLK_PLL2_BUS]);
+
/* Set initial power mode */
imx6q_set_lpm(WAIT_CLOCKED);
}
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 5057d61298b7..4ad6e473cf83 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -329,7 +329,7 @@ static void __init imx6q_opp_check_speed_grading(struct device *cpu_dev)
if (dev_pm_opp_disable(cpu_dev, 852000000))
pr_warn("failed to disable 852 MHz OPP\n");
}
-
+ iounmap(base);
put_node:
of_node_put(np);
}
diff --git a/arch/arm/mach-integrator/pci_v3.c b/arch/arm/mach-integrator/pci_v3.c
index c186a17c2cff..2565f0e7b5cf 100644
--- a/arch/arm/mach-integrator/pci_v3.c
+++ b/arch/arm/mach-integrator/pci_v3.c
@@ -356,7 +356,6 @@ static u64 pre_mem_pci_sz;
* 7:2 register number
*
*/
-static DEFINE_RAW_SPINLOCK(v3_lock);
#undef V3_LB_BASE_PREFETCH
#define V3_LB_BASE_PREFETCH 0
@@ -457,67 +456,21 @@ static void v3_close_config_window(void)
static int v3_read_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 *val)
{
- void __iomem *addr;
- unsigned long flags;
- u32 v;
-
- raw_spin_lock_irqsave(&v3_lock, flags);
- addr = v3_open_config_window(bus, devfn, where);
-
- switch (size) {
- case 1:
- v = __raw_readb(addr);
- break;
-
- case 2:
- v = __raw_readw(addr);
- break;
-
- default:
- v = __raw_readl(addr);
- break;
- }
-
+ int ret = pci_generic_config_read(bus, devfn, where, size, val);
v3_close_config_window();
- raw_spin_unlock_irqrestore(&v3_lock, flags);
-
- *val = v;
- return PCIBIOS_SUCCESSFUL;
+ return ret;
}
static int v3_write_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 val)
{
- void __iomem *addr;
- unsigned long flags;
-
- raw_spin_lock_irqsave(&v3_lock, flags);
- addr = v3_open_config_window(bus, devfn, where);
-
- switch (size) {
- case 1:
- __raw_writeb((u8)val, addr);
- __raw_readb(addr);
- break;
-
- case 2:
- __raw_writew((u16)val, addr);
- __raw_readw(addr);
- break;
-
- case 4:
- __raw_writel(val, addr);
- __raw_readl(addr);
- break;
- }
-
+ int ret = pci_generic_config_write(bus, devfn, where, size, val);
v3_close_config_window();
- raw_spin_unlock_irqrestore(&v3_lock, flags);
-
- return PCIBIOS_SUCCESSFUL;
+ return ret;
}
static struct pci_ops pci_v3_ops = {
+ .map_bus = v3_open_config_window,
.read = v3_read_config,
.write = v3_write_config,
};
@@ -658,7 +611,6 @@ static int __init pci_v3_setup(int nr, struct pci_sys_data *sys)
*/
static void __init pci_v3_preinit(void)
{
- unsigned long flags;
unsigned int temp;
phys_addr_t io_address = pci_pio_to_address(io_mem.start);
@@ -672,8 +624,6 @@ static void __init pci_v3_preinit(void)
hook_fault_code(8, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
hook_fault_code(10, v3_pci_fault, SIGBUS, 0, "external abort on non-linefetch");
- raw_spin_lock_irqsave(&v3_lock, flags);
-
/*
* Unlock V3 registers, but only if they were previously locked.
*/
@@ -736,8 +686,6 @@ static void __init pci_v3_preinit(void)
v3_writew(V3_LB_CFG, v3_readw(V3_LB_CFG) | (1 << 10));
v3_writeb(V3_LB_IMASK, 0x28);
__raw_writel(3, ap_syscon_base + INTEGRATOR_SC_PCIENABLE_OFFSET);
-
- raw_spin_unlock_irqrestore(&v3_lock, flags);
}
static void __init pci_v3_postinit(void)
diff --git a/arch/arm/mach-ks8695/pci.c b/arch/arm/mach-ks8695/pci.c
index bb18193b4bac..c1bc4c3716ed 100644
--- a/arch/arm/mach-ks8695/pci.c
+++ b/arch/arm/mach-ks8695/pci.c
@@ -38,8 +38,6 @@
static int pci_dbg;
-static int pci_cfg_dbg;
-
static void ks8695_pci_setupconfig(unsigned int bus_nr, unsigned int devfn, unsigned int where)
{
@@ -59,75 +57,11 @@ static void ks8695_pci_setupconfig(unsigned int bus_nr, unsigned int devfn, unsi
}
}
-
-/*
- * The KS8695 datasheet prohibits anything other than 32bit accesses
- * to the IO registers, so all our configuration must be done with
- * 32bit operations, and the correct bit masking and shifting.
- */
-
-static int ks8695_pci_readconfig(struct pci_bus *bus,
- unsigned int devfn, int where, int size, u32 *value)
-{
- ks8695_pci_setupconfig(bus->number, devfn, where);
-
- *value = __raw_readl(KS8695_PCI_VA + KS8695_PBCD);
-
- switch (size) {
- case 4:
- break;
- case 2:
- *value = *value >> ((where & 2) * 8);
- *value &= 0xffff;
- break;
- case 1:
- *value = *value >> ((where & 3) * 8);
- *value &= 0xff;
- break;
- }
-
- if (pci_cfg_dbg) {
- printk("read: %d,%08x,%02x,%d: %08x (%08x)\n",
- bus->number, devfn, where, size, *value,
- __raw_readl(KS8695_PCI_VA + KS8695_PBCD));
- }
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int ks8695_pci_writeconfig(struct pci_bus *bus,
- unsigned int devfn, int where, int size, u32 value)
+static void __iomem *ks8695_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
+ int where)
{
- unsigned long tmp;
-
- if (pci_cfg_dbg) {
- printk("write: %d,%08x,%02x,%d: %08x\n",
- bus->number, devfn, where, size, value);
- }
-
ks8695_pci_setupconfig(bus->number, devfn, where);
-
- switch (size) {
- case 4:
- __raw_writel(value, KS8695_PCI_VA + KS8695_PBCD);
- break;
- case 2:
- tmp = __raw_readl(KS8695_PCI_VA + KS8695_PBCD);
- tmp &= ~(0xffff << ((where & 2) * 8));
- tmp |= value << ((where & 2) * 8);
-
- __raw_writel(tmp, KS8695_PCI_VA + KS8695_PBCD);
- break;
- case 1:
- tmp = __raw_readl(KS8695_PCI_VA + KS8695_PBCD);
- tmp &= ~(0xff << ((where & 3) * 8));
- tmp |= value << ((where & 3) * 8);
-
- __raw_writel(tmp, KS8695_PCI_VA + KS8695_PBCD);
- break;
- }
-
- return PCIBIOS_SUCCESSFUL;
+ return KS8695_PCI_VA + KS8695_PBCD;
}
static void ks8695_local_writeconfig(int where, u32 value)
@@ -137,8 +71,9 @@ static void ks8695_local_writeconfig(int where, u32 value)
}
static struct pci_ops ks8695_pci_ops = {
- .read = ks8695_pci_readconfig,
- .write = ks8695_pci_writeconfig,
+ .map_bus = ks8695_pci_map_bus,
+ .read = pci_generic_config_read32,
+ .write = pci_generic_config_write32,
};
static struct resource pci_mem = {
diff --git a/arch/arm/mach-mediatek/Kconfig b/arch/arm/mach-mediatek/Kconfig
index f73f588f649c..f7e463ca0287 100644
--- a/arch/arm/mach-mediatek/Kconfig
+++ b/arch/arm/mach-mediatek/Kconfig
@@ -1,6 +1,26 @@
-config ARCH_MEDIATEK
+menuconfig ARCH_MEDIATEK
bool "Mediatek MT65xx & MT81xx SoC" if ARCH_MULTI_V7
select ARM_GIC
select MTK_TIMER
help
Support for Mediatek MT65xx & MT81xx SoCs
+
+if ARCH_MEDIATEK
+
+config MACH_MT6589
+ bool "MediaTek MT6589 SoCs support"
+ default ARCH_MEDIATEK
+
+config MACH_MT6592
+ bool "MediaTek MT6592 SoCs support"
+ default ARCH_MEDIATEK
+
+config MACH_MT8127
+ bool "MediaTek MT8127 SoCs support"
+ default ARCH_MEDIATEK
+
+config MACH_MT8135
+ bool "MediaTek MT8135 SoCs support"
+ default ARCH_MEDIATEK
+
+endif
diff --git a/arch/arm/mach-mvebu/coherency.c b/arch/arm/mach-mvebu/coherency.c
index 3585cb394e9b..b5895f040caa 100644
--- a/arch/arm/mach-mvebu/coherency.c
+++ b/arch/arm/mach-mvebu/coherency.c
@@ -33,6 +33,7 @@
#include <asm/smp_plat.h>
#include <asm/cacheflush.h>
#include <asm/mach/map.h>
+#include <asm/dma-mapping.h>
#include "coherency.h"
#include "mvebu-soc-id.h"
@@ -76,54 +77,6 @@ int set_cpu_coherent(void)
return ll_enable_coherency();
}
-static inline void mvebu_hwcc_sync_io_barrier(void)
-{
- writel(0x1, coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET);
- while (readl(coherency_cpu_base + IO_SYNC_BARRIER_CTL_OFFSET) & 0x1);
-}
-
-static dma_addr_t mvebu_hwcc_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 (dir != DMA_TO_DEVICE)
- mvebu_hwcc_sync_io_barrier();
- return pfn_to_dma(dev, page_to_pfn(page)) + offset;
-}
-
-
-static void mvebu_hwcc_dma_unmap_page(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction dir,
- struct dma_attrs *attrs)
-{
- if (dir != DMA_TO_DEVICE)
- mvebu_hwcc_sync_io_barrier();
-}
-
-static void mvebu_hwcc_dma_sync(struct device *dev, dma_addr_t dma_handle,
- size_t size, enum dma_data_direction dir)
-{
- if (dir != DMA_TO_DEVICE)
- mvebu_hwcc_sync_io_barrier();
-}
-
-static struct dma_map_ops mvebu_hwcc_dma_ops = {
- .alloc = arm_dma_alloc,
- .free = arm_dma_free,
- .mmap = arm_dma_mmap,
- .map_page = mvebu_hwcc_dma_map_page,
- .unmap_page = mvebu_hwcc_dma_unmap_page,
- .get_sgtable = arm_dma_get_sgtable,
- .map_sg = arm_dma_map_sg,
- .unmap_sg = arm_dma_unmap_sg,
- .sync_single_for_cpu = mvebu_hwcc_dma_sync,
- .sync_single_for_device = mvebu_hwcc_dma_sync,
- .sync_sg_for_cpu = arm_dma_sync_sg_for_cpu,
- .sync_sg_for_device = arm_dma_sync_sg_for_device,
- .set_dma_mask = arm_dma_set_mask,
-};
-
static int mvebu_hwcc_notifier(struct notifier_block *nb,
unsigned long event, void *__dev)
{
@@ -131,7 +84,7 @@ static int mvebu_hwcc_notifier(struct notifier_block *nb,
if (event != BUS_NOTIFY_ADD_DEVICE)
return NOTIFY_DONE;
- set_dma_ops(dev, &mvebu_hwcc_dma_ops);
+ set_dma_ops(dev, &arm_coherent_dma_ops);
return NOTIFY_OK;
}
@@ -190,6 +143,13 @@ static void __init armada_375_380_coherency_init(struct device_node *np)
arch_ioremap_caller = armada_pcie_wa_ioremap_caller;
/*
+ * We should switch the PL310 to I/O coherency mode only if
+ * I/O coherency is actually enabled.
+ */
+ if (!coherency_available())
+ return;
+
+ /*
* Add the PL310 property "arm,io-coherent". This makes sure the
* outer sync operation is not used, which allows to
* workaround the system erratum that causes deadlocks when
diff --git a/arch/arm/mach-mvebu/mvebu-soc-id.h b/arch/arm/mach-mvebu/mvebu-soc-id.h
index c16bb68ca81f..e124a0b82a3e 100644
--- a/arch/arm/mach-mvebu/mvebu-soc-id.h
+++ b/arch/arm/mach-mvebu/mvebu-soc-id.h
@@ -20,10 +20,28 @@
#define MV78XX0_A0_REV 0x1
#define MV78XX0_B0_REV 0x2
+/* Amada 370 ID */
+#define ARMADA_370_DEV_ID 0x6710
+
+/* Amada 370 Revision */
+#define ARMADA_370_A1_REV 0x1
+
+/* Armada 375 ID */
+#define ARMADA_375_DEV_ID 0x6720
+
/* Armada 375 */
#define ARMADA_375_Z1_REV 0x0
#define ARMADA_375_A0_REV 0x3
+/* Armada 38x ID */
+#define ARMADA_380_DEV_ID 0x6810
+#define ARMADA_385_DEV_ID 0x6820
+#define ARMADA_388_DEV_ID 0x6828
+
+/* Armada 38x Revision */
+#define ARMADA_38x_Z1_REV 0x0
+#define ARMADA_38x_A0_REV 0x4
+
#ifdef CONFIG_ARCH_MVEBU
int mvebu_get_soc_id(u32 *dev, u32 *rev);
#else
diff --git a/arch/arm/mach-omap1/include/mach/debug-macro.S b/arch/arm/mach-omap1/include/mach/debug-macro.S
deleted file mode 100644
index 5c1a26c9f490..000000000000
--- a/arch/arm/mach-omap1/include/mach/debug-macro.S
+++ /dev/null
@@ -1,101 +0,0 @@
-/* arch/arm/mach-omap1/include/mach/debug-macro.S
- *
- * Debugging macro include header
- *
- * Copyright (C) 1994-1999 Russell King
- * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
-*/
-
-#include <linux/serial_reg.h>
-
-#include "serial.h"
-
- .pushsection .data
-omap_uart_phys: .word 0x0
-omap_uart_virt: .word 0x0
- .popsection
-
- /*
- * Note that this code won't work if the bootloader passes
- * a wrong machine ID number in r1. To debug, just hardcode
- * the desired UART phys and virt addresses temporarily into
- * the omap_uart_phys and omap_uart_virt above.
- */
- .macro addruart, rp, rv, tmp
-
- /* Use omap_uart_phys/virt if already configured */
-9: adr \rp, 99f @ get effective addr of 99f
- ldr \rv, [\rp] @ get absolute addr of 99f
- sub \rv, \rv, \rp @ offset between the two
- ldr \rp, [\rp, #4] @ abs addr of omap_uart_phys
- sub \tmp, \rp, \rv @ make it effective
- ldr \rp, [\tmp, #0] @ omap_uart_phys
- ldr \rv, [\tmp, #4] @ omap_uart_virt
- cmp \rp, #0 @ is port configured?
- cmpne \rv, #0
- bne 100f @ already configured
-
- /* Check the debug UART configuration set in uncompress.h */
- and \rp, pc, #0xff000000
- ldr \rv, =OMAP_UART_INFO_OFS
- ldr \rp, [\rp, \rv]
-
- /* Select the UART to use based on the UART1 scratchpad value */
-10: cmp \rp, #0 @ no port configured?
- beq 11f @ if none, try to use UART1
- cmp \rp, #OMAP1UART1
- beq 11f @ configure OMAP1UART1
- cmp \rp, #OMAP1UART2
- beq 12f @ configure OMAP1UART2
- cmp \rp, #OMAP1UART3
- beq 13f @ configure OMAP2UART3
-
- /* Configure the UART offset from the phys/virt base */
-11: mov \rp, #0x00fb0000 @ OMAP1UART1
- b 98f
-12: mov \rp, #0x00fb0000 @ OMAP1UART1
- orr \rp, \rp, #0x00000800 @ OMAP1UART2
- b 98f
-13: mov \rp, #0x00fb0000 @ OMAP1UART1
- orr \rp, \rp, #0x00000800 @ OMAP1UART2
- orr \rp, \rp, #0x00009000 @ OMAP1UART3
-
- /* Store both phys and virt address for the uart */
-98: add \rp, \rp, #0xff000000 @ phys base
- str \rp, [\tmp, #0] @ omap_uart_phys
- sub \rp, \rp, #0xff000000 @ phys base
- add \rp, \rp, #0xfe000000 @ virt base
- str \rp, [\tmp, #4] @ omap_uart_virt
- b 9b
-
- .align
-99: .word .
- .word omap_uart_phys
- .ltorg
-
-100:
- .endm
-
- .macro senduart,rd,rx
- strb \rd, [\rx]
- .endm
-
- .macro busyuart,rd,rx
-1001: ldrb \rd, [\rx, #(UART_LSR << OMAP_PORT_SHIFT)]
- and \rd, \rd, #(UART_LSR_TEMT | UART_LSR_THRE)
- teq \rd, #(UART_LSR_TEMT | UART_LSR_THRE)
- beq 1002f
- ldrb \rd, [\rx, #(UART_LSR << OMAP7XX_PORT_SHIFT)]
- and \rd, \rd, #(UART_LSR_TEMT | UART_LSR_THRE)
- teq \rd, #(UART_LSR_TEMT | UART_LSR_THRE)
- bne 1001b
-1002:
- .endm
-
- .macro waituart,rd,rx
- .endm
diff --git a/arch/arm/mach-omap1/irq.c b/arch/arm/mach-omap1/irq.c
index 122ef67939a2..a8a533df24e1 100644
--- a/arch/arm/mach-omap1/irq.c
+++ b/arch/arm/mach-omap1/irq.c
@@ -64,11 +64,6 @@ u32 omap_irq_flags;
static unsigned int irq_bank_count;
static struct omap_irq_bank *irq_banks;
-static inline unsigned int irq_bank_readl(int bank, int offset)
-{
- return omap_readl(irq_banks[bank].base_reg + offset);
-}
-
static inline void irq_bank_writel(unsigned long value, int bank, int offset)
{
omap_writel(value, irq_banks[bank].base_reg + offset);
diff --git a/arch/arm/mach-omap1/timer32k.c b/arch/arm/mach-omap1/timer32k.c
index 107e7ab3edba..36bf174b3fac 100644
--- a/arch/arm/mach-omap1/timer32k.c
+++ b/arch/arm/mach-omap1/timer32k.c
@@ -91,11 +91,6 @@ static inline void omap_32k_timer_write(int val, int reg)
omap_writew(val, OMAP1_32K_TIMER_BASE + reg);
}
-static inline unsigned long omap_32k_timer_read(int reg)
-{
- return omap_readl(OMAP1_32K_TIMER_BASE + reg) & 0xffffff;
-}
-
static inline void omap_32k_timer_start(unsigned long load_val)
{
if (!load_val)
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 6ab656cc4f16..2b8e47788062 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -217,12 +217,6 @@ config MACH_OMAP3517EVM
bool "OMAP3517/ AM3517 EVM board"
depends on ARCH_OMAP3
default y
- select OMAP_PACKAGE_CBB
-
-config MACH_CRANEBOARD
- bool "AM3517/05 CRANE board"
- depends on ARCH_OMAP3
- select OMAP_PACKAGE_CBB
config MACH_OMAP3_PANDORA
bool "OMAP3 Pandora"
@@ -263,12 +257,6 @@ config MACH_CM_T35
select MACH_CM_T3730
select OMAP_PACKAGE_CUS
-config MACH_CM_T3517
- bool "CompuLab CM-T3517 module"
- depends on ARCH_OMAP3
- default y
- select OMAP_PACKAGE_CBB
-
config MACH_CM_T3730
bool
diff --git a/arch/arm/mach-omap2/Makefile b/arch/arm/mach-omap2/Makefile
index 5d27dfdef66b..00d5d8f9f150 100644
--- a/arch/arm/mach-omap2/Makefile
+++ b/arch/arm/mach-omap2/Makefile
@@ -58,6 +58,7 @@ AFLAGS_sram34xx.o :=-Wa,-march=armv7-a
# Restart code (OMAP4/5 currently in omap4-common.c)
obj-$(CONFIG_SOC_OMAP2420) += omap2-restart.o
obj-$(CONFIG_SOC_OMAP2430) += omap2-restart.o
+obj-$(CONFIG_SOC_TI81XX) += ti81xx-restart.o
obj-$(CONFIG_SOC_AM33XX) += am33xx-restart.o
obj-$(CONFIG_SOC_AM43XX) += omap4-restart.o
obj-$(CONFIG_ARCH_OMAP3) += omap3-restart.o
@@ -120,6 +121,7 @@ obj-$(CONFIG_ARCH_OMAP4) += $(omap-prcm-4-5-common)
obj-$(CONFIG_SOC_OMAP5) += $(omap-prcm-4-5-common)
obj-$(CONFIG_SOC_DRA7XX) += $(omap-prcm-4-5-common)
am33xx-43xx-prcm-common += prm33xx.o cm33xx.o
+obj-$(CONFIG_SOC_TI81XX) += $(am33xx-43xx-prcm-common)
obj-$(CONFIG_SOC_AM33XX) += $(am33xx-43xx-prcm-common)
obj-$(CONFIG_SOC_AM43XX) += $(omap-prcm-4-5-common) \
$(am33xx-43xx-prcm-common)
@@ -170,6 +172,8 @@ obj-$(CONFIG_ARCH_OMAP4) += $(clockdomain-common)
obj-$(CONFIG_ARCH_OMAP4) += clockdomains44xx_data.o
obj-$(CONFIG_SOC_AM33XX) += $(clockdomain-common)
obj-$(CONFIG_SOC_AM33XX) += clockdomains33xx_data.o
+obj-$(CONFIG_SOC_TI81XX) += $(clockdomain-common)
+obj-$(CONFIG_SOC_TI81XX) += clockdomains81xx_data.o
obj-$(CONFIG_SOC_AM43XX) += $(clockdomain-common)
obj-$(CONFIG_SOC_AM43XX) += clockdomains43xx_data.o
obj-$(CONFIG_SOC_OMAP5) += $(clockdomain-common)
@@ -181,7 +185,6 @@ obj-$(CONFIG_SOC_DRA7XX) += clockdomains7xx_data.o
obj-$(CONFIG_ARCH_OMAP2) += $(clock-common) clock2xxx.o
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpllcore.o
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_virt_prcm_set.o
-obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_apll.o
obj-$(CONFIG_ARCH_OMAP2) += clkt2xxx_dpll.o clkt_iclk.o
obj-$(CONFIG_SOC_OMAP2430) += clock2430.o
obj-$(CONFIG_ARCH_OMAP3) += $(clock-common) clock3xxx.o
@@ -223,6 +226,7 @@ obj-$(CONFIG_SOC_AM33XX) += omap_hwmod_33xx_43xx_ipblock_data.o
obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_43xx_data.o
obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_33xx_43xx_interconnect_data.o
obj-$(CONFIG_SOC_AM43XX) += omap_hwmod_33xx_43xx_ipblock_data.o
+obj-$(CONFIG_SOC_TI81XX) += omap_hwmod_81xx_data.o
obj-$(CONFIG_ARCH_OMAP4) += omap_hwmod_44xx_data.o
obj-$(CONFIG_SOC_OMAP5) += omap_hwmod_54xx_data.o
obj-$(CONFIG_SOC_DRA7XX) += omap_hwmod_7xx_data.o
@@ -250,13 +254,8 @@ obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51.o sdram-nokia.o
obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-peripherals.o
obj-$(CONFIG_MACH_NOKIA_RX51) += board-rx51-video.o
obj-$(CONFIG_MACH_CM_T35) += board-cm-t35.o
-obj-$(CONFIG_MACH_CM_T3517) += board-cm-t3517.o
obj-$(CONFIG_MACH_TOUCHBOOK) += board-omap3touchbook.o
-obj-$(CONFIG_MACH_OMAP3517EVM) += board-am3517evm.o
-
-obj-$(CONFIG_MACH_CRANEBOARD) += board-am3517crane.o
-
obj-$(CONFIG_MACH_SBC3530) += board-omap3stalker.o
# Platform specific device init code
@@ -286,7 +285,4 @@ ifneq ($(CONFIG_HWSPINLOCK_OMAP),)
obj-y += hwspinlock.o
endif
-emac-$(CONFIG_TI_DAVINCI_EMAC) := am35xx-emac.o
-obj-y += $(emac-m) $(emac-y)
-
obj-y += common-board-devices.o twl-common.o dss-common.o
diff --git a/arch/arm/mach-omap2/am35xx-emac.c b/arch/arm/mach-omap2/am35xx-emac.c
deleted file mode 100644
index 6a6935caac1e..000000000000
--- a/arch/arm/mach-omap2/am35xx-emac.c
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2011 Ilya Yanok, Emcraft Systems
- *
- * Based on mach-omap2/board-am3517evm.c
- * Copyright (C) 2009 Texas Instruments Incorporated
- * Author: Ranjith Lohithakshan <ranjithl@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * published by the Free Software Foundation.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
- * whether express or implied; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- */
-
-#include <linux/err.h>
-#include <linux/davinci_emac.h>
-#include "omap_device.h"
-#include "am35xx.h"
-#include "control.h"
-#include "am35xx-emac.h"
-
-static void am35xx_enable_emac_int(void)
-{
- u32 v;
-
- v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
- v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR |
- AM35XX_CPGMAC_C0_MISC_PULSE_CLR | AM35XX_CPGMAC_C0_RX_THRESH_CLR);
- omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR);
- omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */
-}
-
-static void am35xx_disable_emac_int(void)
-{
- u32 v;
-
- v = omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR);
- v |= (AM35XX_CPGMAC_C0_RX_PULSE_CLR | AM35XX_CPGMAC_C0_TX_PULSE_CLR);
- omap_ctrl_writel(v, AM35XX_CONTROL_LVL_INTR_CLEAR);
- omap_ctrl_readl(AM35XX_CONTROL_LVL_INTR_CLEAR); /* OCP barrier */
-}
-
-static struct emac_platform_data am35xx_emac_pdata = {
- .ctrl_reg_offset = AM35XX_EMAC_CNTRL_OFFSET,
- .ctrl_mod_reg_offset = AM35XX_EMAC_CNTRL_MOD_OFFSET,
- .ctrl_ram_offset = AM35XX_EMAC_CNTRL_RAM_OFFSET,
- .ctrl_ram_size = AM35XX_EMAC_CNTRL_RAM_SIZE,
- .hw_ram_addr = AM35XX_EMAC_HW_RAM_ADDR,
- .version = EMAC_VERSION_2,
- .interrupt_enable = am35xx_enable_emac_int,
- .interrupt_disable = am35xx_disable_emac_int,
-};
-
-static struct mdio_platform_data am35xx_mdio_pdata;
-
-static int __init omap_davinci_emac_dev_init(struct omap_hwmod *oh,
- void *pdata, int pdata_len)
-{
- struct platform_device *pdev;
-
- pdev = omap_device_build(oh->class->name, 0, oh, pdata, pdata_len);
- if (IS_ERR(pdev)) {
- WARN(1, "Can't build omap_device for %s:%s.\n",
- oh->class->name, oh->name);
- return PTR_ERR(pdev);
- }
-
- return 0;
-}
-
-void __init am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en)
-{
- struct omap_hwmod *oh;
- u32 v;
- int ret;
-
- oh = omap_hwmod_lookup("davinci_mdio");
- if (!oh) {
- pr_err("Could not find davinci_mdio hwmod\n");
- return;
- }
-
- am35xx_mdio_pdata.bus_freq = mdio_bus_freq;
-
- ret = omap_davinci_emac_dev_init(oh, &am35xx_mdio_pdata,
- sizeof(am35xx_mdio_pdata));
- if (ret) {
- pr_err("Could not build davinci_mdio hwmod device\n");
- return;
- }
-
- oh = omap_hwmod_lookup("davinci_emac");
- if (!oh) {
- pr_err("Could not find davinci_emac hwmod\n");
- return;
- }
-
- am35xx_emac_pdata.rmii_en = rmii_en;
-
- ret = omap_davinci_emac_dev_init(oh, &am35xx_emac_pdata,
- sizeof(am35xx_emac_pdata));
- if (ret) {
- pr_err("Could not build davinci_emac hwmod device\n");
- return;
- }
-
- v = omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET);
- v &= ~AM35XX_CPGMACSS_SW_RST;
- omap_ctrl_writel(v, AM35XX_CONTROL_IP_SW_RESET);
- omap_ctrl_readl(AM35XX_CONTROL_IP_SW_RESET); /* OCP barrier */
-}
diff --git a/arch/arm/mach-omap2/am35xx-emac.h b/arch/arm/mach-omap2/am35xx-emac.h
deleted file mode 100644
index 15c6f9ce59a2..000000000000
--- a/arch/arm/mach-omap2/am35xx-emac.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright (C) 2011 Ilya Yanok, Emcraft Systems
- *
- * 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.
- */
-
-#define AM35XX_DEFAULT_MDIO_FREQUENCY 1000000
-
-#if defined(CONFIG_TI_DAVINCI_EMAC) || defined(CONFIG_TI_DAVINCI_EMAC_MODULE)
-void am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en);
-#else
-static inline void am35xx_emac_init(unsigned long mdio_bus_freq, u8 rmii_en) {}
-#endif
diff --git a/arch/arm/mach-omap2/am35xx.h b/arch/arm/mach-omap2/am35xx.h
deleted file mode 100644
index 95594495fcf6..000000000000
--- a/arch/arm/mach-omap2/am35xx.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*:
- * Address mappings and base address for AM35XX specific interconnects
- * and peripherals.
- *
- * Copyright (C) 2009 Texas Instruments
- *
- * Author: Sriramakrishnan <srk@ti.com>
- * Vaibhav Hiremath <hvaibhav@ti.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#ifndef __ASM_ARCH_AM35XX_H
-#define __ASM_ARCH_AM35XX_H
-
-/*
- * Base addresses
- * Note: OMAP3430 IVA2 memory space is being used for AM35xx IPSS modules
- */
-#define AM35XX_IPSS_EMAC_BASE 0x5C000000
-#define AM35XX_IPSS_USBOTGSS_BASE 0x5C040000
-#define AM35XX_IPSS_HECC_BASE 0x5C050000
-#define AM35XX_IPSS_VPFE_BASE 0x5C060000
-
-
-/* HECC module specifc offset definitions */
-#define AM35XX_HECC_SCC_HECC_OFFSET (0x0)
-#define AM35XX_HECC_SCC_RAM_OFFSET (0x3000)
-#define AM35XX_HECC_RAM_OFFSET (0x3000)
-#define AM35XX_HECC_MBOX_OFFSET (0x2000)
-#define AM35XX_HECC_INT_LINE (0x0)
-#define AM35XX_HECC_VERSION (0x1)
-
-#define AM35XX_EMAC_CNTRL_OFFSET (0x10000)
-#define AM35XX_EMAC_CNTRL_MOD_OFFSET (0x0)
-#define AM35XX_EMAC_CNTRL_RAM_OFFSET (0x20000)
-#define AM35XX_EMAC_MDIO_OFFSET (0x30000)
-#define AM35XX_IPSS_MDIO_BASE (AM35XX_IPSS_EMAC_BASE + \
- AM35XX_EMAC_MDIO_OFFSET)
-#define AM35XX_EMAC_CNTRL_RAM_SIZE (0x2000)
-#define AM35XX_EMAC_RAM_ADDR (AM3517_EMAC_BASE + \
- AM3517_EMAC_CNTRL_RAM_OFFSET)
-#define AM35XX_EMAC_HW_RAM_ADDR (0x01E20000)
-
-#endif /* __ASM_ARCH_AM35XX_H */
diff --git a/arch/arm/mach-omap2/board-am3517crane.c b/arch/arm/mach-omap2/board-am3517crane.c
deleted file mode 100644
index 8168ddabaeda..000000000000
--- a/arch/arm/mach-omap2/board-am3517crane.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Support for AM3517/05 Craneboard
- * http://www.mistralsolutions.com/products/craneboard.php
- *
- * Copyright (C) 2010 Mistral Solutions Pvt Ltd. <www.mistralsolutions.com>
- * Author: R.Srinath <srinath@mistralsolutions.com>
- *
- * Based on mach-omap2/board-am3517evm.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 version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
- * whether express or implied; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/gpio.h>
-#include <linux/mfd/tps65910.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-#include <linux/omap-gpmc.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "common.h"
-#include "common-board-devices.h"
-#include "board-flash.h"
-
-#include "am35xx-emac.h"
-#include "mux.h"
-#include "control.h"
-
-#define GPIO_USB_POWER 35
-#define GPIO_USB_NRESET 38
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
- OMAP3_MUX(SYS_NIRQ, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLUP),
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#endif
-
-static struct usbhs_phy_data phy_data[] __initdata = {
- {
- .port = 1,
- .reset_gpio = GPIO_USB_NRESET,
- .vcc_gpio = GPIO_USB_POWER,
- .vcc_polarity = 1,
- },
-};
-
-static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
- .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
-};
-
-static struct mtd_partition crane_nand_partitions[] = {
- {
- .name = "X-Loader",
- .offset = 0,
- .size = 4 * NAND_BLOCK_SIZE,
- .mask_flags = MTD_WRITEABLE,
- },
- {
- .name = "U-Boot",
- .offset = MTDPART_OFS_APPEND,
- .size = 14 * NAND_BLOCK_SIZE,
- .mask_flags = MTD_WRITEABLE,
- },
- {
- .name = "U-Boot Env",
- .offset = MTDPART_OFS_APPEND,
- .size = 2 * NAND_BLOCK_SIZE,
- },
- {
- .name = "Kernel",
- .offset = MTDPART_OFS_APPEND,
- .size = 40 * NAND_BLOCK_SIZE,
- },
- {
- .name = "File System",
- .offset = MTDPART_OFS_APPEND,
- .size = MTDPART_SIZ_FULL,
- },
-};
-
-static struct tps65910_board tps65910_pdata = {
- .irq = 7 + OMAP_INTC_START,
- .en_ck32k_xtal = true,
-};
-
-static struct i2c_board_info __initdata tps65910_board_info[] = {
- {
- I2C_BOARD_INFO("tps65910", 0x2d),
- .platform_data = &tps65910_pdata,
- },
-};
-
-static void __init am3517_crane_i2c_init(void)
-{
- omap_register_i2c_bus(1, 2600, tps65910_board_info,
- ARRAY_SIZE(tps65910_board_info));
-}
-
-static void __init am3517_crane_init(void)
-{
- omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
- omap_serial_init();
- omap_sdrc_init(NULL, NULL);
- board_nand_init(crane_nand_partitions,
- ARRAY_SIZE(crane_nand_partitions), 0,
- NAND_BUSWIDTH_16, NULL);
- am3517_crane_i2c_init();
-
- /* Configure GPIO for EHCI port */
- if (omap_mux_init_gpio(GPIO_USB_NRESET, OMAP_PIN_OUTPUT)) {
- pr_err("Can not configure mux for GPIO_USB_NRESET %d\n",
- GPIO_USB_NRESET);
- return;
- }
-
- if (omap_mux_init_gpio(GPIO_USB_POWER, OMAP_PIN_OUTPUT)) {
- pr_err("Can not configure mux for GPIO_USB_POWER %d\n",
- GPIO_USB_POWER);
- return;
- }
-
- usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
- usbhs_init(&usbhs_bdata);
- am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1);
-}
-
-MACHINE_START(CRANEBOARD, "AM3517/05 CRANEBOARD")
- .atag_offset = 0x100,
- .reserve = omap_reserve,
- .map_io = omap3_map_io,
- .init_early = am35xx_init_early,
- .init_irq = omap3_init_irq,
- .init_machine = am3517_crane_init,
- .init_late = am35xx_init_late,
- .init_time = omap3_sync32k_timer_init,
- .restart = omap3xxx_restart,
-MACHINE_END
diff --git a/arch/arm/mach-omap2/board-am3517evm.c b/arch/arm/mach-omap2/board-am3517evm.c
deleted file mode 100644
index 1c091b3fa312..000000000000
--- a/arch/arm/mach-omap2/board-am3517evm.c
+++ /dev/null
@@ -1,373 +0,0 @@
-/*
- * linux/arch/arm/mach-omap2/board-am3517evm.c
- *
- * Copyright (C) 2009 Texas Instruments Incorporated
- * Author: Ranjith Lohithakshan <ranjithl@ti.com>
- *
- * Based on mach-omap2/board-omap3evm.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 version 2.
- *
- * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
- * whether express or implied; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/clk.h>
-#include <linux/platform_device.h>
-#include <linux/gpio.h>
-#include <linux/platform_data/pca953x.h>
-#include <linux/can/platform/ti_hecc.h>
-#include <linux/davinci_emac.h>
-#include <linux/mmc/host.h>
-#include <linux/usb/musb.h>
-#include <linux/platform_data/gpio-omap.h>
-
-#include "am35xx.h"
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "common.h"
-#include <video/omapdss.h>
-#include <video/omap-panel-data.h>
-
-#include "am35xx-emac.h"
-#include "mux.h"
-#include "control.h"
-#include "hsmmc.h"
-
-#define LCD_PANEL_PWR 176
-#define LCD_PANEL_BKLIGHT_PWR 182
-#define LCD_PANEL_PWM 181
-
-static struct i2c_board_info __initdata am3517evm_i2c1_boardinfo[] = {
- {
- I2C_BOARD_INFO("s35390a", 0x30),
- },
-};
-
-/*
- * RTC - S35390A
- */
-#define GPIO_RTCS35390A_IRQ 55
-
-static void __init am3517_evm_rtc_init(void)
-{
- int r;
-
- omap_mux_init_gpio(GPIO_RTCS35390A_IRQ, OMAP_PIN_INPUT_PULLUP);
-
- r = gpio_request_one(GPIO_RTCS35390A_IRQ, GPIOF_IN, "rtcs35390a-irq");
- if (r < 0) {
- printk(KERN_WARNING "failed to request GPIO#%d\n",
- GPIO_RTCS35390A_IRQ);
- return;
- }
-
- am3517evm_i2c1_boardinfo[0].irq = gpio_to_irq(GPIO_RTCS35390A_IRQ);
-}
-
-/*
- * I2C GPIO Expander - TCA6416
- */
-
-/* Mounted on Base-Board */
-static struct pca953x_platform_data am3517evm_gpio_expander_info_0 = {
- .gpio_base = OMAP_MAX_GPIO_LINES,
-};
-static struct i2c_board_info __initdata am3517evm_i2c2_boardinfo[] = {
- {
- I2C_BOARD_INFO("tlv320aic23", 0x1A),
- },
- {
- I2C_BOARD_INFO("tca6416", 0x21),
- .platform_data = &am3517evm_gpio_expander_info_0,
- },
-};
-
-/* Mounted on UI Card */
-static struct pca953x_platform_data am3517evm_ui_gpio_expander_info_1 = {
- .gpio_base = OMAP_MAX_GPIO_LINES + 16,
-};
-static struct pca953x_platform_data am3517evm_ui_gpio_expander_info_2 = {
- .gpio_base = OMAP_MAX_GPIO_LINES + 32,
-};
-static struct i2c_board_info __initdata am3517evm_i2c3_boardinfo[] = {
- {
- I2C_BOARD_INFO("tca6416", 0x20),
- .platform_data = &am3517evm_ui_gpio_expander_info_1,
- },
- {
- I2C_BOARD_INFO("tca6416", 0x21),
- .platform_data = &am3517evm_ui_gpio_expander_info_2,
- },
-};
-
-static int __init am3517_evm_i2c_init(void)
-{
- omap_register_i2c_bus(1, 400, NULL, 0);
- omap_register_i2c_bus(2, 400, am3517evm_i2c2_boardinfo,
- ARRAY_SIZE(am3517evm_i2c2_boardinfo));
- omap_register_i2c_bus(3, 400, am3517evm_i2c3_boardinfo,
- ARRAY_SIZE(am3517evm_i2c3_boardinfo));
-
- return 0;
-}
-
-static const struct display_timing am3517_evm_lcd_videomode = {
- .pixelclock = { 0, 9000000, 0 },
-
- .hactive = { 0, 480, 0 },
- .hfront_porch = { 0, 3, 0 },
- .hback_porch = { 0, 2, 0 },
- .hsync_len = { 0, 42, 0 },
-
- .vactive = { 0, 272, 0 },
- .vfront_porch = { 0, 3, 0 },
- .vback_porch = { 0, 2, 0 },
- .vsync_len = { 0, 11, 0 },
-
- .flags = DISPLAY_FLAGS_HSYNC_LOW | DISPLAY_FLAGS_VSYNC_LOW |
- DISPLAY_FLAGS_DE_LOW | DISPLAY_FLAGS_PIXDATA_POSEDGE,
-};
-
-static struct panel_dpi_platform_data am3517_evm_lcd_pdata = {
- .name = "lcd",
- .source = "dpi.0",
-
- .data_lines = 16,
-
- .display_timing = &am3517_evm_lcd_videomode,
-
- .enable_gpio = LCD_PANEL_PWR,
- .backlight_gpio = LCD_PANEL_BKLIGHT_PWR,
-};
-
-static struct platform_device am3517_evm_lcd_device = {
- .name = "panel-dpi",
- .id = 0,
- .dev.platform_data = &am3517_evm_lcd_pdata,
-};
-
-static struct connector_dvi_platform_data am3517_evm_dvi_connector_pdata = {
- .name = "dvi",
- .source = "tfp410.0",
- .i2c_bus_num = -1,
-};
-
-static struct platform_device am3517_evm_dvi_connector_device = {
- .name = "connector-dvi",
- .id = 0,
- .dev.platform_data = &am3517_evm_dvi_connector_pdata,
-};
-
-static struct encoder_tfp410_platform_data am3517_evm_tfp410_pdata = {
- .name = "tfp410.0",
- .source = "dpi.0",
- .data_lines = 24,
- .power_down_gpio = -1,
-};
-
-static struct platform_device am3517_evm_tfp410_device = {
- .name = "tfp410",
- .id = 0,
- .dev.platform_data = &am3517_evm_tfp410_pdata,
-};
-
-static struct connector_atv_platform_data am3517_evm_tv_pdata = {
- .name = "tv",
- .source = "venc.0",
- .connector_type = OMAP_DSS_VENC_TYPE_SVIDEO,
- .invert_polarity = false,
-};
-
-static struct platform_device am3517_evm_tv_connector_device = {
- .name = "connector-analog-tv",
- .id = 0,
- .dev.platform_data = &am3517_evm_tv_pdata,
-};
-
-static struct omap_dss_board_info am3517_evm_dss_data = {
- .default_display_name = "lcd",
-};
-
-static void __init am3517_evm_display_init(void)
-{
- gpio_request_one(LCD_PANEL_PWM, GPIOF_OUT_INIT_HIGH, "lcd panel pwm");
-
- omap_display_init(&am3517_evm_dss_data);
-
- platform_device_register(&am3517_evm_tfp410_device);
- platform_device_register(&am3517_evm_dvi_connector_device);
- platform_device_register(&am3517_evm_lcd_device);
- platform_device_register(&am3517_evm_tv_connector_device);
-}
-
-/*
- * Board initialization
- */
-
-static struct omap_musb_board_data musb_board_data = {
- .interface_type = MUSB_INTERFACE_ULPI,
- .mode = MUSB_OTG,
- .power = 500,
- .set_phy_power = am35x_musb_phy_power,
- .clear_irq = am35x_musb_clear_irq,
- .set_mode = am35x_set_mode,
- .reset = am35x_musb_reset,
-};
-
-static __init void am3517_evm_musb_init(void)
-{
- u32 devconf2;
-
- /*
- * Set up USB clock/mode in the DEVCONF2 register.
- */
- devconf2 = omap_ctrl_readl(AM35XX_CONTROL_DEVCONF2);
-
- /* USB2.0 PHY reference clock is 13 MHz */
- devconf2 &= ~(CONF2_REFFREQ | CONF2_OTGMODE | CONF2_PHY_GPIOMODE);
- devconf2 |= CONF2_REFFREQ_13MHZ | CONF2_SESENDEN | CONF2_VBDTCTEN
- | CONF2_DATPOL;
-
- omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
-
- usb_musb_init(&musb_board_data);
-}
-
-static __init void am3517_evm_mcbsp1_init(void)
-{
- u32 devconf0;
-
- /* McBSP1 CLKR/FSR signal to be connected to CLKX/FSX pin */
- devconf0 = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
- devconf0 |= OMAP2_MCBSP1_CLKR_MASK | OMAP2_MCBSP1_FSR_MASK;
- omap_ctrl_writel(devconf0, OMAP2_CONTROL_DEVCONF0);
-}
-
-static struct usbhs_phy_data phy_data[] __initdata = {
- {
- .port = 1,
- .reset_gpio = 57,
- .vcc_gpio = -EINVAL,
- },
-};
-
-static struct usbhs_omap_platform_data usbhs_bdata __initdata = {
- .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-};
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
- /* USB OTG DRVVBUS offset = 0x212 */
- OMAP3_MUX(SAD2D_MCAD23, OMAP_MUX_MODE0 | OMAP_PIN_INPUT_PULLDOWN),
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#endif
-
-
-static struct resource am3517_hecc_resources[] = {
- {
- .start = AM35XX_IPSS_HECC_BASE,
- .end = AM35XX_IPSS_HECC_BASE + 0x3FFF,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = 24 + OMAP_INTC_START,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct platform_device am3517_hecc_device = {
- .name = "ti_hecc",
- .id = -1,
- .num_resources = ARRAY_SIZE(am3517_hecc_resources),
- .resource = am3517_hecc_resources,
-};
-
-static struct ti_hecc_platform_data am3517_evm_hecc_pdata = {
- .scc_hecc_offset = AM35XX_HECC_SCC_HECC_OFFSET,
- .scc_ram_offset = AM35XX_HECC_SCC_RAM_OFFSET,
- .hecc_ram_offset = AM35XX_HECC_RAM_OFFSET,
- .mbx_offset = AM35XX_HECC_MBOX_OFFSET,
- .int_line = AM35XX_HECC_INT_LINE,
- .version = AM35XX_HECC_VERSION,
-};
-
-static void am3517_evm_hecc_init(struct ti_hecc_platform_data *pdata)
-{
- am3517_hecc_device.dev.platform_data = pdata;
- platform_device_register(&am3517_hecc_device);
-}
-
-static struct omap2_hsmmc_info mmc[] = {
- {
- .mmc = 1,
- .caps = MMC_CAP_4_BIT_DATA,
- .gpio_cd = 127,
- .gpio_wp = 126,
- },
- {
- .mmc = 2,
- .caps = MMC_CAP_4_BIT_DATA,
- .gpio_cd = 128,
- .gpio_wp = 129,
- },
- {} /* Terminator */
-};
-
-static void __init am3517_evm_init(void)
-{
- omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
-
- am3517_evm_i2c_init();
-
- am3517_evm_display_init();
-
- omap_serial_init();
- omap_sdrc_init(NULL, NULL);
-
- /* Configure GPIO for EHCI port */
- omap_mux_init_gpio(57, OMAP_PIN_OUTPUT);
-
- usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
- usbhs_init(&usbhs_bdata);
- am3517_evm_hecc_init(&am3517_evm_hecc_pdata);
-
- /* RTC - S35390A */
- am3517_evm_rtc_init();
-
- i2c_register_board_info(1, am3517evm_i2c1_boardinfo,
- ARRAY_SIZE(am3517evm_i2c1_boardinfo));
- /*Ethernet*/
- am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1);
-
- /* MUSB */
- am3517_evm_musb_init();
-
- /* McBSP1 */
- am3517_evm_mcbsp1_init();
-
- /* MMC init function */
- omap_hsmmc_init(mmc);
-}
-
-MACHINE_START(OMAP3517EVM, "OMAP3517/AM3517 EVM")
- .atag_offset = 0x100,
- .reserve = omap_reserve,
- .map_io = omap3_map_io,
- .init_early = am35xx_init_early,
- .init_irq = omap3_init_irq,
- .init_machine = am3517_evm_init,
- .init_late = am35xx_init_late,
- .init_time = omap3_sync32k_timer_init,
- .restart = omap3xxx_restart,
-MACHINE_END
diff --git a/arch/arm/mach-omap2/board-cm-t3517.c b/arch/arm/mach-omap2/board-cm-t3517.c
deleted file mode 100644
index 794756df8529..000000000000
--- a/arch/arm/mach-omap2/board-cm-t3517.c
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
- * linux/arch/arm/mach-omap2/board-cm-t3517.c
- *
- * Support for the CompuLab CM-T3517 modules
- *
- * Copyright (C) 2010 CompuLab, Ltd.
- * Author: Igor Grinberg <grinberg@compulab.co.il>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA
- *
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/platform_device.h>
-#include <linux/delay.h>
-#include <linux/gpio.h>
-#include <linux/leds.h>
-#include <linux/omap-gpmc.h>
-#include <linux/rtc-v3020.h>
-#include <linux/mtd/mtd.h>
-#include <linux/mtd/nand.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mmc/host.h>
-#include <linux/can/platform/ti_hecc.h>
-
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <asm/mach/map.h>
-
-#include "common.h"
-#include <linux/platform_data/mtd-nand-omap2.h>
-
-#include "am35xx.h"
-
-#include "mux.h"
-#include "control.h"
-#include "hsmmc.h"
-#include "common-board-devices.h"
-#include "am35xx-emac.h"
-
-#if defined(CONFIG_LEDS_GPIO) || defined(CONFIG_LEDS_GPIO_MODULE)
-static struct gpio_led cm_t3517_leds[] = {
- [0] = {
- .gpio = 186,
- .name = "cm-t3517:green",
- .default_trigger = "heartbeat",
- .active_low = 0,
- },
-};
-
-static struct gpio_led_platform_data cm_t3517_led_pdata = {
- .num_leds = ARRAY_SIZE(cm_t3517_leds),
- .leds = cm_t3517_leds,
-};
-
-static struct platform_device cm_t3517_led_device = {
- .name = "leds-gpio",
- .id = -1,
- .dev = {
- .platform_data = &cm_t3517_led_pdata,
- },
-};
-
-static void __init cm_t3517_init_leds(void)
-{
- platform_device_register(&cm_t3517_led_device);
-}
-#else
-static inline void cm_t3517_init_leds(void) {}
-#endif
-
-#if defined(CONFIG_CAN_TI_HECC) || defined(CONFIG_CAN_TI_HECC_MODULE)
-static struct resource cm_t3517_hecc_resources[] = {
- {
- .start = AM35XX_IPSS_HECC_BASE,
- .end = AM35XX_IPSS_HECC_BASE + SZ_16K - 1,
- .flags = IORESOURCE_MEM,
- },
- {
- .start = 24 + OMAP_INTC_START,
- .flags = IORESOURCE_IRQ,
- },
-};
-
-static struct ti_hecc_platform_data cm_t3517_hecc_pdata = {
- .scc_hecc_offset = AM35XX_HECC_SCC_HECC_OFFSET,
- .scc_ram_offset = AM35XX_HECC_SCC_RAM_OFFSET,
- .hecc_ram_offset = AM35XX_HECC_RAM_OFFSET,
- .mbx_offset = AM35XX_HECC_MBOX_OFFSET,
- .int_line = AM35XX_HECC_INT_LINE,
- .version = AM35XX_HECC_VERSION,
-};
-
-static struct platform_device cm_t3517_hecc_device = {
- .name = "ti_hecc",
- .id = 1,
- .num_resources = ARRAY_SIZE(cm_t3517_hecc_resources),
- .resource = cm_t3517_hecc_resources,
- .dev = {
- .platform_data = &cm_t3517_hecc_pdata,
- },
-};
-
-static void cm_t3517_init_hecc(void)
-{
- platform_device_register(&cm_t3517_hecc_device);
-}
-#else
-static inline void cm_t3517_init_hecc(void) {}
-#endif
-
-#if defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
-static struct omap2_hsmmc_info cm_t3517_mmc[] = {
- {
- .mmc = 1,
- .caps = MMC_CAP_4_BIT_DATA,
- .gpio_cd = 144,
- .gpio_wp = 59,
- },
- {
- .mmc = 2,
- .caps = MMC_CAP_4_BIT_DATA,
- .gpio_cd = -EINVAL,
- .gpio_wp = -EINVAL,
- },
- {} /* Terminator */
-};
-#else
-#define cm_t3517_mmc NULL
-#endif
-
-#if defined(CONFIG_RTC_DRV_V3020) || defined(CONFIG_RTC_DRV_V3020_MODULE)
-#define RTC_IO_GPIO (153)
-#define RTC_WR_GPIO (154)
-#define RTC_RD_GPIO (53)
-#define RTC_CS_GPIO (163)
-#define RTC_CS_EN_GPIO (160)
-
-struct v3020_platform_data cm_t3517_v3020_pdata = {
- .use_gpio = 1,
- .gpio_cs = RTC_CS_GPIO,
- .gpio_wr = RTC_WR_GPIO,
- .gpio_rd = RTC_RD_GPIO,
- .gpio_io = RTC_IO_GPIO,
-};
-
-static struct platform_device cm_t3517_rtc_device = {
- .name = "v3020",
- .id = -1,
- .dev = {
- .platform_data = &cm_t3517_v3020_pdata,
- }
-};
-
-static void __init cm_t3517_init_rtc(void)
-{
- int err;
-
- err = gpio_request_one(RTC_CS_EN_GPIO, GPIOF_OUT_INIT_HIGH,
- "rtc cs en");
- if (err) {
- pr_err("CM-T3517: rtc cs en gpio request failed: %d\n", err);
- return;
- }
-
- platform_device_register(&cm_t3517_rtc_device);
-}
-#else
-static inline void cm_t3517_init_rtc(void) {}
-#endif
-
-#if defined(CONFIG_USB_EHCI_HCD) || defined(CONFIG_USB_EHCI_HCD_MODULE)
-#define HSUSB1_RESET_GPIO (146)
-#define HSUSB2_RESET_GPIO (147)
-#define USB_HUB_RESET_GPIO (152)
-
-static struct usbhs_phy_data phy_data[] __initdata = {
- {
- .port = 1,
- .reset_gpio = HSUSB1_RESET_GPIO,
- .vcc_gpio = -EINVAL,
- },
- {
- .port = 2,
- .reset_gpio = HSUSB2_RESET_GPIO,
- .vcc_gpio = -EINVAL,
- },
-};
-
-static struct usbhs_omap_platform_data cm_t3517_ehci_pdata __initdata = {
- .port_mode[0] = OMAP_EHCI_PORT_MODE_PHY,
- .port_mode[1] = OMAP_EHCI_PORT_MODE_PHY,
-};
-
-static int __init cm_t3517_init_usbh(void)
-{
- int err;
-
- err = gpio_request_one(USB_HUB_RESET_GPIO, GPIOF_OUT_INIT_LOW,
- "usb hub rst");
- if (err) {
- pr_err("CM-T3517: usb hub rst gpio request failed: %d\n", err);
- } else {
- udelay(10);
- gpio_set_value(USB_HUB_RESET_GPIO, 1);
- msleep(1);
- }
-
- usbhs_init_phys(phy_data, ARRAY_SIZE(phy_data));
- usbhs_init(&cm_t3517_ehci_pdata);
-
- return 0;
-}
-#else
-static inline int cm_t3517_init_usbh(void)
-{
- return 0;
-}
-#endif
-
-#if defined(CONFIG_MTD_NAND_OMAP2) || defined(CONFIG_MTD_NAND_OMAP2_MODULE)
-static struct mtd_partition cm_t3517_nand_partitions[] = {
- {
- .name = "xloader",
- .offset = 0, /* Offset = 0x00000 */
- .size = 4 * NAND_BLOCK_SIZE,
- .mask_flags = MTD_WRITEABLE
- },
- {
- .name = "uboot",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x80000 */
- .size = 15 * NAND_BLOCK_SIZE,
- },
- {
- .name = "uboot environment",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x260000 */
- .size = 2 * NAND_BLOCK_SIZE,
- },
- {
- .name = "linux",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x2A0000 */
- .size = 32 * NAND_BLOCK_SIZE,
- },
- {
- .name = "rootfs",
- .offset = MTDPART_OFS_APPEND, /* Offset = 0x6A0000 */
- .size = MTDPART_SIZ_FULL,
- },
-};
-
-static struct omap_nand_platform_data cm_t3517_nand_data = {
- .parts = cm_t3517_nand_partitions,
- .nr_parts = ARRAY_SIZE(cm_t3517_nand_partitions),
- .cs = 0,
-};
-
-static void __init cm_t3517_init_nand(void)
-{
- if (gpmc_nand_init(&cm_t3517_nand_data, NULL) < 0)
- pr_err("CM-T3517: NAND initialization failed\n");
-}
-#else
-static inline void cm_t3517_init_nand(void) {}
-#endif
-
-#ifdef CONFIG_OMAP_MUX
-static struct omap_board_mux board_mux[] __initdata = {
- /* GPIO186 - Green LED */
- OMAP3_MUX(SYS_CLKOUT2, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
-
- /* RTC GPIOs: */
- /* IO - GPIO153 */
- OMAP3_MUX(MCBSP4_DR, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
- /* WR# - GPIO154 */
- OMAP3_MUX(MCBSP4_DX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
- /* RD# - GPIO53 */
- OMAP3_MUX(GPMC_NCS2, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
- /* CS# - GPIO163 */
- OMAP3_MUX(UART3_CTS_RCTX, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
- /* CS EN - GPIO160 */
- OMAP3_MUX(MCBSP_CLKS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT),
-
- /* HSUSB1 RESET */
- OMAP3_MUX(UART2_TX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
- /* HSUSB2 RESET */
- OMAP3_MUX(UART2_RX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
- /* CM-T3517 USB HUB nRESET */
- OMAP3_MUX(MCBSP4_CLKX, OMAP_MUX_MODE4 | OMAP_PIN_OUTPUT),
-
- /* CD - GPIO144 and WP - GPIO59 for MMC1 - SB-T35 */
- OMAP3_MUX(UART2_CTS, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
- OMAP3_MUX(GPMC_CLK, OMAP_MUX_MODE4 | OMAP_PIN_INPUT_PULLUP),
-
- { .reg_offset = OMAP_MUX_TERMINATOR },
-};
-#endif
-
-static void __init cm_t3517_init(void)
-{
- omap3_mux_init(board_mux, OMAP_PACKAGE_CBB);
- omap_serial_init();
- omap_sdrc_init(NULL, NULL);
- cm_t3517_init_leds();
- cm_t3517_init_nand();
- cm_t3517_init_rtc();
- cm_t3517_init_usbh();
- cm_t3517_init_hecc();
- am35xx_emac_init(AM35XX_DEFAULT_MDIO_FREQUENCY, 1);
- omap_hsmmc_init(cm_t3517_mmc);
-}
-
-MACHINE_START(CM_T3517, "Compulab CM-T3517")
- .atag_offset = 0x100,
- .reserve = omap_reserve,
- .map_io = omap3_map_io,
- .init_early = am35xx_init_early,
- .init_irq = omap3_init_irq,
- .init_machine = cm_t3517_init,
- .init_late = am35xx_init_late,
- .init_time = omap3_gptimer_timer_init,
- .restart = omap3xxx_restart,
-MACHINE_END
diff --git a/arch/arm/mach-omap2/board-generic.c b/arch/arm/mach-omap2/board-generic.c
index 608079a1aba6..34ff14b7beab 100644
--- a/arch/arm/mach-omap2/board-generic.c
+++ b/arch/arm/mach-omap2/board-generic.c
@@ -77,6 +77,24 @@ MACHINE_END
#endif
#ifdef CONFIG_ARCH_OMAP3
+/* Some boards need board name for legacy userspace in /proc/cpuinfo */
+static const char *const n900_boards_compat[] __initconst = {
+ "nokia,omap3-n900",
+ NULL,
+};
+
+DT_MACHINE_START(OMAP3_N900_DT, "Nokia RX-51 board")
+ .reserve = omap_reserve,
+ .map_io = omap3_map_io,
+ .init_early = omap3430_init_early,
+ .init_machine = omap_generic_init,
+ .init_late = omap3_init_late,
+ .init_time = omap3_sync32k_timer_init,
+ .dt_compat = n900_boards_compat,
+ .restart = omap3xxx_restart,
+MACHINE_END
+
+/* Generic omap3 boards, most boards can use these */
static const char *const omap3_boards_compat[] __initconst = {
"ti,omap3430",
"ti,omap3",
@@ -144,6 +162,42 @@ DT_MACHINE_START(AM3517_DT, "Generic AM3517 (Flattened Device Tree)")
MACHINE_END
#endif
+#ifdef CONFIG_SOC_TI81XX
+static const char *const ti814x_boards_compat[] __initconst = {
+ "ti,dm8148",
+ "ti,dm814",
+ NULL,
+};
+
+DT_MACHINE_START(TI81XX_DT, "Generic ti814x (Flattened Device Tree)")
+ .reserve = omap_reserve,
+ .map_io = ti81xx_map_io,
+ .init_early = ti814x_init_early,
+ .init_machine = omap_generic_init,
+ .init_late = ti81xx_init_late,
+ .init_time = omap3_gptimer_timer_init,
+ .dt_compat = ti814x_boards_compat,
+ .restart = ti81xx_restart,
+MACHINE_END
+
+static const char *const ti816x_boards_compat[] __initconst = {
+ "ti,dm8168",
+ "ti,dm816",
+ NULL,
+};
+
+DT_MACHINE_START(TI816X_DT, "Generic ti816x (Flattened Device Tree)")
+ .reserve = omap_reserve,
+ .map_io = ti81xx_map_io,
+ .init_early = ti816x_init_early,
+ .init_machine = omap_generic_init,
+ .init_late = ti81xx_init_late,
+ .init_time = omap3_gptimer_timer_init,
+ .dt_compat = ti816x_boards_compat,
+ .restart = ti81xx_restart,
+MACHINE_END
+#endif
+
#ifdef CONFIG_SOC_AM33XX
static const char *const am33xx_boards_compat[] __initconst = {
"ti,am33xx",
@@ -171,6 +225,9 @@ static const char *const omap4_boards_compat[] __initconst = {
};
DT_MACHINE_START(OMAP4_DT, "Generic OMAP4 (Flattened Device Tree)")
+ .l2c_aux_val = OMAP_L2C_AUX_CTRL,
+ .l2c_aux_mask = 0xcf9fffff,
+ .l2c_write_sec = omap4_l2c310_write_sec,
.reserve = omap_reserve,
.smp = smp_ops(omap4_smp_ops),
.map_io = omap4_map_io,
@@ -214,6 +271,9 @@ static const char *const am43_boards_compat[] __initconst = {
};
DT_MACHINE_START(AM43_DT, "Generic AM43 (Flattened Device Tree)")
+ .l2c_aux_val = OMAP_L2C_AUX_CTRL,
+ .l2c_aux_mask = 0xcf9fffff,
+ .l2c_write_sec = omap4_l2c310_write_sec,
.map_io = am33xx_map_io,
.init_early = am43xx_init_early,
.init_late = am43xx_init_late,
diff --git a/arch/arm/mach-omap2/board-omap3pandora.c b/arch/arm/mach-omap2/board-omap3pandora.c
index 7f1708738c30..969e1003dd92 100644
--- a/arch/arm/mach-omap2/board-omap3pandora.c
+++ b/arch/arm/mach-omap2/board-omap3pandora.c
@@ -254,12 +254,14 @@ static void pandora_wl1251_init_card(struct mmc_card *card)
* We have TI wl1251 attached to MMC3. Pass this information to
* SDIO core because it can't be probed by normal methods.
*/
- card->quirks |= MMC_QUIRK_NONSTD_SDIO;
- card->cccr.wide_bus = 1;
- card->cis.vendor = 0x104c;
- card->cis.device = 0x9066;
- card->cis.blksize = 512;
- card->cis.max_dtr = 20000000;
+ if (card->type == MMC_TYPE_SDIO || card->type == MMC_TYPE_SD_COMBO) {
+ card->quirks |= MMC_QUIRK_NONSTD_SDIO;
+ card->cccr.wide_bus = 1;
+ card->cis.vendor = 0x104c;
+ card->cis.device = 0x9066;
+ card->cis.blksize = 512;
+ card->cis.max_dtr = 20000000;
+ }
}
static struct omap2_hsmmc_info omap3pandora_mmc[] = {
diff --git a/arch/arm/mach-omap2/cclock3xxx_data.c b/arch/arm/mach-omap2/cclock3xxx_data.c
index 644ff3231bb8..e79c80bbc755 100644
--- a/arch/arm/mach-omap2/cclock3xxx_data.c
+++ b/arch/arm/mach-omap2/cclock3xxx_data.c
@@ -3634,10 +3634,6 @@ int __init omap3xxx_clk_init(void)
omap_clocks_register(omap36xx_am35xx_omap3430es2plus_clks,
ARRAY_SIZE(omap36xx_am35xx_omap3430es2plus_clks));
omap_clocks_register(omap3xxx_clks, ARRAY_SIZE(omap3xxx_clks));
- } else if (soc_is_am33xx()) {
- cpu_mask = RATE_IN_AM33XX;
- } else if (cpu_is_ti814x()) {
- cpu_mask = RATE_IN_TI814X;
} else if (cpu_is_omap34xx()) {
if (omap_rev() == OMAP3430_REV_ES1_0) {
cpu_mask = RATE_IN_3430ES1;
@@ -3681,7 +3677,7 @@ int __init omap3xxx_clk_init(void)
* Lock DPLL5 -- here only until other device init code can
* handle this
*/
- if (!cpu_is_ti81xx() && (omap_rev() >= OMAP3430_REV_ES2_0))
+ if (omap_rev() >= OMAP3430_REV_ES2_0)
omap3_clk_lock_dpll5();
/* Avoid sleeping during omap3_core_dpll_m2_set_rate() */
diff --git a/arch/arm/mach-omap2/clkt2xxx_apll.c b/arch/arm/mach-omap2/clkt2xxx_apll.c
deleted file mode 100644
index c78e893eba7d..000000000000
--- a/arch/arm/mach-omap2/clkt2xxx_apll.c
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * OMAP2xxx APLL clock control functions
- *
- * Copyright (C) 2005-2008 Texas Instruments, Inc.
- * Copyright (C) 2004-2010 Nokia Corporation
- *
- * Contacts:
- * Richard Woodruff <r-woodruff2@ti.com>
- * Paul Walmsley
- *
- * Based on earlier work by Tuukka Tikkanen, Tony Lindgren,
- * Gordon McNutt and RidgeRun, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-#undef DEBUG
-
-#include <linux/kernel.h>
-#include <linux/clk.h>
-#include <linux/io.h>
-
-
-#include "clock.h"
-#include "clock2xxx.h"
-#include "cm2xxx.h"
-#include "cm-regbits-24xx.h"
-
-/* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */
-#define EN_APLL_STOPPED 0
-#define EN_APLL_LOCKED 3
-
-/* CM_CLKSEL1_PLL.APLLS_CLKIN options (24XX) */
-#define APLLS_CLKIN_19_2MHZ 0
-#define APLLS_CLKIN_13MHZ 2
-#define APLLS_CLKIN_12MHZ 3
-
-/* Private functions */
-
-/**
- * omap2xxx_clk_apll_locked - is the APLL locked?
- * @hw: struct clk_hw * of the APLL to check
- *
- * If the APLL IP block referred to by @hw indicates that it's locked,
- * return true; otherwise, return false.
- */
-static bool omap2xxx_clk_apll_locked(struct clk_hw *hw)
-{
- struct clk_hw_omap *clk = to_clk_hw_omap(hw);
- u32 r, apll_mask;
-
- apll_mask = EN_APLL_LOCKED << clk->enable_bit;
-
- r = omap2xxx_cm_get_pll_status();
-
- return ((r & apll_mask) == apll_mask) ? true : false;
-}
-
-int omap2_clk_apll96_enable(struct clk_hw *hw)
-{
- return omap2xxx_cm_apll96_enable();
-}
-
-int omap2_clk_apll54_enable(struct clk_hw *hw)
-{
- return omap2xxx_cm_apll54_enable();
-}
-
-static void _apll96_allow_idle(struct clk_hw_omap *clk)
-{
- omap2xxx_cm_set_apll96_auto_low_power_stop();
-}
-
-static void _apll96_deny_idle(struct clk_hw_omap *clk)
-{
- omap2xxx_cm_set_apll96_disable_autoidle();
-}
-
-static void _apll54_allow_idle(struct clk_hw_omap *clk)
-{
- omap2xxx_cm_set_apll54_auto_low_power_stop();
-}
-
-static void _apll54_deny_idle(struct clk_hw_omap *clk)
-{
- omap2xxx_cm_set_apll54_disable_autoidle();
-}
-
-void omap2_clk_apll96_disable(struct clk_hw *hw)
-{
- omap2xxx_cm_apll96_disable();
-}
-
-void omap2_clk_apll54_disable(struct clk_hw *hw)
-{
- omap2xxx_cm_apll54_disable();
-}
-
-unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw,
- unsigned long parent_rate)
-{
- return (omap2xxx_clk_apll_locked(hw)) ? 54000000 : 0;
-}
-
-unsigned long omap2_clk_apll96_recalc(struct clk_hw *hw,
- unsigned long parent_rate)
-{
- return (omap2xxx_clk_apll_locked(hw)) ? 96000000 : 0;
-}
-
-/* Public data */
-const struct clk_hw_omap_ops clkhwops_apll54 = {
- .allow_idle = _apll54_allow_idle,
- .deny_idle = _apll54_deny_idle,
-};
-
-const struct clk_hw_omap_ops clkhwops_apll96 = {
- .allow_idle = _apll96_allow_idle,
- .deny_idle = _apll96_deny_idle,
-};
-
-/* Public functions */
-
-u32 omap2xxx_get_apll_clkin(void)
-{
- u32 aplls, srate = 0;
-
- aplls = omap2xxx_cm_get_pll_config();
- aplls &= OMAP24XX_APLLS_CLKIN_MASK;
- aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT;
-
- if (aplls == APLLS_CLKIN_19_2MHZ)
- srate = 19200000;
- else if (aplls == APLLS_CLKIN_13MHZ)
- srate = 13000000;
- else if (aplls == APLLS_CLKIN_12MHZ)
- srate = 12000000;
-
- return srate;
-}
-
diff --git a/arch/arm/mach-omap2/clock.c b/arch/arm/mach-omap2/clock.c
index 6ad5b4dbd33e..4ae4ccebced2 100644
--- a/arch/arm/mach-omap2/clock.c
+++ b/arch/arm/mach-omap2/clock.c
@@ -620,6 +620,9 @@ void omap2_clk_enable_init_clocks(const char **clk_names, u8 num_clocks)
for (i = 0; i < num_clocks; i++) {
init_clk = clk_get(NULL, clk_names[i]);
+ if (WARN(IS_ERR(init_clk), "could not find init clock %s\n",
+ clk_names[i]))
+ continue;
clk_prepare_enable(init_clk);
}
}
diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
index a4282e79143e..1cf9dd85248a 100644
--- a/arch/arm/mach-omap2/clock.h
+++ b/arch/arm/mach-omap2/clock.h
@@ -177,7 +177,6 @@ struct clksel {
u32 omap3_dpll_autoidle_read(struct clk_hw_omap *clk);
void omap3_dpll_allow_idle(struct clk_hw_omap *clk);
void omap3_dpll_deny_idle(struct clk_hw_omap *clk);
-int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk);
void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk);
void omap4_dpllmx_deny_gatectrl(struct clk_hw_omap *clk);
diff --git a/arch/arm/mach-omap2/clock2xxx.h b/arch/arm/mach-omap2/clock2xxx.h
index a090225ceeba..125c37614848 100644
--- a/arch/arm/mach-omap2/clock2xxx.h
+++ b/arch/arm/mach-omap2/clock2xxx.h
@@ -22,12 +22,7 @@ unsigned long omap2xxx_sys_clk_recalc(struct clk_hw *clk,
unsigned long omap2_osc_clk_recalc(struct clk_hw *clk,
unsigned long parent_rate);
void omap2xxx_clkt_dpllcore_init(struct clk_hw *hw);
-unsigned long omap2_clk_apll54_recalc(struct clk_hw *hw,
- unsigned long parent_rate);
-unsigned long omap2_clk_apll96_recalc(struct clk_hw *hw,
- unsigned long parent_rate);
unsigned long omap2xxx_clk_get_core_rate(void);
-u32 omap2xxx_get_apll_clkin(void);
u32 omap2xxx_get_sysclkdiv(void);
void omap2xxx_clk_prepare_for_reboot(void);
void omap2xxx_clkt_vps_check_bootloader_rates(void);
@@ -46,11 +41,5 @@ int omap2430_clk_init(void);
#endif
extern struct clk_hw *dclk_hw;
-int omap2_enable_osc_ck(struct clk_hw *hw);
-void omap2_disable_osc_ck(struct clk_hw *hw);
-int omap2_clk_apll96_enable(struct clk_hw *hw);
-int omap2_clk_apll54_enable(struct clk_hw *hw);
-void omap2_clk_apll96_disable(struct clk_hw *hw);
-void omap2_clk_apll54_disable(struct clk_hw *hw);
#endif
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h
index 82c37b1becc4..77bab5fb6814 100644
--- a/arch/arm/mach-omap2/clockdomain.h
+++ b/arch/arm/mach-omap2/clockdomain.h
@@ -216,6 +216,7 @@ extern void __init omap242x_clockdomains_init(void);
extern void __init omap243x_clockdomains_init(void);
extern void __init omap3xxx_clockdomains_init(void);
extern void __init am33xx_clockdomains_init(void);
+extern void __init ti81xx_clockdomains_init(void);
extern void __init omap44xx_clockdomains_init(void);
extern void __init omap54xx_clockdomains_init(void);
extern void __init dra7xx_clockdomains_init(void);
diff --git a/arch/arm/mach-omap2/clockdomains81xx_data.c b/arch/arm/mach-omap2/clockdomains81xx_data.c
new file mode 100644
index 000000000000..ce2a82001d0d
--- /dev/null
+++ b/arch/arm/mach-omap2/clockdomains81xx_data.c
@@ -0,0 +1,194 @@
+/*
+ * TI81XX Clock Domain data.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/
+ * Copyright (C) 2013 SKTB SKiT, http://www.skitlab.ru/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_81XX_H
+#define __ARCH_ARM_MACH_OMAP2_CLOCKDOMAINS_81XX_H
+
+#include <linux/kernel.h>
+#include <linux/io.h>
+
+#include "clockdomain.h"
+#include "cm81xx.h"
+
+/*
+ * Note that 814x seems to have HWSUP_SWSUP for many clockdomains
+ * while 816x does not. According to the TRM, 816x only has HWSUP
+ * for ALWON_L3_FAST. Also note that the TI tree clockdomains81xx.h
+ * seems to have the related ifdef the wrong way around claiming
+ * 816x supports HWSUP while 814x does not. For now, we only set
+ * HWSUP for ALWON_L3_FAST as that seems to be supported for both
+ * dm814x and dm816x.
+ */
+
+/* Common for 81xx */
+
+static struct clockdomain alwon_l3_slow_81xx_clkdm = {
+ .name = "alwon_l3s_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_ALWON_L3_SLOW_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain alwon_l3_med_81xx_clkdm = {
+ .name = "alwon_l3_med_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_ALWON_L3_MED_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain alwon_l3_fast_81xx_clkdm = {
+ .name = "alwon_l3_fast_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_ALWON_L3_FAST_CLKDM,
+ .flags = CLKDM_CAN_HWSUP_SWSUP,
+};
+
+static struct clockdomain alwon_ethernet_81xx_clkdm = {
+ .name = "alwon_ethernet_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_ETHERNET_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain mmu_81xx_clkdm = {
+ .name = "mmu_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_MMU_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain mmu_cfg_81xx_clkdm = {
+ .name = "mmu_cfg_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_MMUCFG_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+/* 816x only */
+
+static struct clockdomain alwon_mpu_816x_clkdm = {
+ .name = "alwon_mpu_clkdm",
+ .pwrdm = { .name = "alwon_pwrdm" },
+ .cm_inst = TI81XX_CM_ALWON_MOD,
+ .clkdm_offs = TI81XX_CM_ALWON_MPU_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain active_gem_816x_clkdm = {
+ .name = "active_gem_clkdm",
+ .pwrdm = { .name = "active_pwrdm" },
+ .cm_inst = TI816X_CM_ACTIVE_MOD,
+ .clkdm_offs = TI816X_CM_ACTIVE_GEM_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain ivahd0_816x_clkdm = {
+ .name = "ivahd0_clkdm",
+ .pwrdm = { .name = "ivahd0_pwrdm" },
+ .cm_inst = TI816X_CM_IVAHD0_MOD,
+ .clkdm_offs = TI816X_CM_IVAHD0_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain ivahd1_816x_clkdm = {
+ .name = "ivahd1_clkdm",
+ .pwrdm = { .name = "ivahd1_pwrdm" },
+ .cm_inst = TI816X_CM_IVAHD1_MOD,
+ .clkdm_offs = TI816X_CM_IVAHD1_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain ivahd2_816x_clkdm = {
+ .name = "ivahd2_clkdm",
+ .pwrdm = { .name = "ivahd2_pwrdm" },
+ .cm_inst = TI816X_CM_IVAHD2_MOD,
+ .clkdm_offs = TI816X_CM_IVAHD2_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain sgx_816x_clkdm = {
+ .name = "sgx_clkdm",
+ .pwrdm = { .name = "sgx_pwrdm" },
+ .cm_inst = TI816X_CM_SGX_MOD,
+ .clkdm_offs = TI816X_CM_SGX_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain default_l3_med_816x_clkdm = {
+ .name = "default_l3_med_clkdm",
+ .pwrdm = { .name = "default_pwrdm" },
+ .cm_inst = TI816X_CM_DEFAULT_MOD,
+ .clkdm_offs = TI816X_CM_DEFAULT_L3_MED_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain default_ducati_816x_clkdm = {
+ .name = "default_ducati_clkdm",
+ .pwrdm = { .name = "default_pwrdm" },
+ .cm_inst = TI816X_CM_DEFAULT_MOD,
+ .clkdm_offs = TI816X_CM_DEFAULT_DUCATI_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain default_pci_816x_clkdm = {
+ .name = "default_pci_clkdm",
+ .pwrdm = { .name = "default_pwrdm" },
+ .cm_inst = TI816X_CM_DEFAULT_MOD,
+ .clkdm_offs = TI816X_CM_DEFAULT_PCI_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain default_l3_slow_816x_clkdm = {
+ .name = "default_l3_slow_clkdm",
+ .pwrdm = { .name = "default_pwrdm" },
+ .cm_inst = TI816X_CM_DEFAULT_MOD,
+ .clkdm_offs = TI816X_CM_DEFAULT_L3_SLOW_CLKDM,
+ .flags = CLKDM_CAN_SWSUP,
+};
+
+static struct clockdomain *clockdomains_ti81xx[] __initdata = {
+ &alwon_mpu_816x_clkdm,
+ &alwon_l3_slow_81xx_clkdm,
+ &alwon_l3_med_81xx_clkdm,
+ &alwon_l3_fast_81xx_clkdm,
+ &alwon_ethernet_81xx_clkdm,
+ &mmu_81xx_clkdm,
+ &mmu_cfg_81xx_clkdm,
+ &active_gem_816x_clkdm,
+ &ivahd0_816x_clkdm,
+ &ivahd1_816x_clkdm,
+ &ivahd2_816x_clkdm,
+ &sgx_816x_clkdm,
+ &default_l3_med_816x_clkdm,
+ &default_ducati_816x_clkdm,
+ &default_pci_816x_clkdm,
+ &default_l3_slow_816x_clkdm,
+ NULL,
+};
+
+void __init ti81xx_clockdomains_init(void)
+{
+ clkdm_register_platform_funcs(&am33xx_clkdm_operations);
+ clkdm_register_clkdms(clockdomains_ti81xx);
+ clkdm_complete_init();
+}
+#endif
diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c
index a96d901b1d5d..ef62ac9dcd05 100644
--- a/arch/arm/mach-omap2/cm2xxx.c
+++ b/arch/arm/mach-omap2/cm2xxx.c
@@ -370,16 +370,6 @@ u32 omap2xxx_cm_get_core_pll_config(void)
return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
}
-u32 omap2xxx_cm_get_pll_config(void)
-{
- return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKSEL1);
-}
-
-u32 omap2xxx_cm_get_pll_status(void)
-{
- return omap2_cm_read_mod_reg(PLL_MOD, CM_CLKEN);
-}
-
void omap2xxx_cm_set_mod_dividers(u32 mpu, u32 dsp, u32 gfx, u32 core, u32 mdm)
{
u32 tmp;
diff --git a/arch/arm/mach-omap2/cm2xxx.h b/arch/arm/mach-omap2/cm2xxx.h
index c89502b168ae..83b6c597b0e1 100644
--- a/arch/arm/mach-omap2/cm2xxx.h
+++ b/arch/arm/mach-omap2/cm2xxx.h
@@ -60,8 +60,6 @@ extern int omap2xxx_cm_fclks_active(void);
extern int omap2xxx_cm_mpu_retention_allowed(void);
extern u32 omap2xxx_cm_get_core_clk_src(void);
extern u32 omap2xxx_cm_get_core_pll_config(void);
-extern u32 omap2xxx_cm_get_pll_config(void);
-extern u32 omap2xxx_cm_get_pll_status(void);
extern void omap2xxx_cm_set_mod_dividers(u32 mpu, u32 dsp, u32 gfx, u32 core,
u32 mdm);
diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c
index b9ad463a368a..cc5aac784278 100644
--- a/arch/arm/mach-omap2/cm33xx.c
+++ b/arch/arm/mach-omap2/cm33xx.c
@@ -72,27 +72,6 @@ static inline u32 am33xx_cm_rmw_reg_bits(u32 mask, u32 bits, s16 inst, s16 idx)
return v;
}
-static inline u32 am33xx_cm_set_reg_bits(u32 bits, s16 inst, s16 idx)
-{
- return am33xx_cm_rmw_reg_bits(bits, bits, inst, idx);
-}
-
-static inline u32 am33xx_cm_clear_reg_bits(u32 bits, s16 inst, s16 idx)
-{
- return am33xx_cm_rmw_reg_bits(bits, 0x0, inst, idx);
-}
-
-static inline u32 am33xx_cm_read_reg_bits(u16 inst, s16 idx, u32 mask)
-{
- u32 v;
-
- v = am33xx_cm_read_reg(inst, idx);
- v &= mask;
- v >>= __ffs(mask);
-
- return v;
-}
-
/**
* _clkctrl_idlest - read a CM_*_CLKCTRL register; mask & shift IDLEST bitfield
* @inst: CM instance register offset (*_INST macro)
diff --git a/arch/arm/mach-omap2/cm81xx.h b/arch/arm/mach-omap2/cm81xx.h
new file mode 100644
index 000000000000..45cb407da222
--- /dev/null
+++ b/arch/arm/mach-omap2/cm81xx.h
@@ -0,0 +1,61 @@
+/*
+ * Clock domain register offsets for TI81XX.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/
+ * Copyright (C) 2013 SKTB SKiT, http://www.skitlab.ru/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ARCH_ARM_MACH_OMAP2_CM_TI81XX_H
+#define __ARCH_ARM_MACH_OMAP2_CM_TI81XX_H
+
+/* TI81XX common CM module offsets */
+#define TI81XX_CM_ALWON_MOD 0x1400 /* 1KB */
+
+/* TI816X CM module offsets */
+#define TI816X_CM_ACTIVE_MOD 0x0400 /* 256B */
+#define TI816X_CM_DEFAULT_MOD 0x0500 /* 256B */
+#define TI816X_CM_IVAHD0_MOD 0x0600 /* 256B */
+#define TI816X_CM_IVAHD1_MOD 0x0700 /* 256B */
+#define TI816X_CM_IVAHD2_MOD 0x0800 /* 256B */
+#define TI816X_CM_SGX_MOD 0x0900 /* 256B */
+
+/* ALWON */
+#define TI81XX_CM_ALWON_L3_SLOW_CLKDM 0x0000
+#define TI81XX_CM_ALWON_L3_MED_CLKDM 0x0004
+#define TI81XX_CM_ETHERNET_CLKDM 0x0004
+#define TI81XX_CM_MMU_CLKDM 0x000C
+#define TI81XX_CM_MMUCFG_CLKDM 0x0010
+#define TI81XX_CM_ALWON_MPU_CLKDM 0x001C
+#define TI81XX_CM_ALWON_L3_FAST_CLKDM 0x0030
+
+/* ACTIVE */
+#define TI816X_CM_ACTIVE_GEM_CLKDM 0x0000
+
+/* IVAHD0 */
+#define TI816X_CM_IVAHD0_CLKDM 0x0000
+
+/* IVAHD1 */
+#define TI816X_CM_IVAHD1_CLKDM 0x0000
+
+/* IVAHD2 */
+#define TI816X_CM_IVAHD2_CLKDM 0x0000
+
+/* SGX */
+#define TI816X_CM_SGX_CLKDM 0x0000
+
+/* DEFAULT */
+#define TI816X_CM_DEFAULT_L3_MED_CLKDM 0x0004
+#define TI816X_CM_DEFAULT_PCI_CLKDM 0x0010
+#define TI816X_CM_DEFAULT_L3_SLOW_CLKDM 0x0014
+#define TI816X_CM_DEFAULT_DUCATI_CLKDM 0x0018
+
+#endif
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index 377eea849e7b..46e24581d624 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -35,6 +35,7 @@
#include <linux/irqchip/irq-omap-intc.h>
#include <asm/proc-fns.h>
+#include <asm/hardware/cache-l2x0.h>
#include "i2c.h"
#include "serial.h"
@@ -94,11 +95,18 @@ extern void omap3_gptimer_timer_init(void);
extern void omap4_local_timer_init(void);
#ifdef CONFIG_CACHE_L2X0
int omap_l2_cache_init(void);
+#define OMAP_L2C_AUX_CTRL (L2C_AUX_CTRL_SHARED_OVERRIDE | \
+ L310_AUX_CTRL_DATA_PREFETCH | \
+ L310_AUX_CTRL_INSTR_PREFETCH)
+void omap4_l2c310_write_sec(unsigned long val, unsigned reg);
#else
static inline int omap_l2_cache_init(void)
{
return 0;
}
+
+#define OMAP_L2C_AUX_CTRL 0
+#define omap4_l2c310_write_sec NULL
#endif
extern void omap5_realtime_timer_init(void);
@@ -110,7 +118,8 @@ void omap3630_init_early(void);
void omap3_init_early(void); /* Do not use this one */
void am33xx_init_early(void);
void am35xx_init_early(void);
-void ti81xx_init_early(void);
+void ti814x_init_early(void);
+void ti816x_init_early(void);
void am33xx_init_early(void);
void am43xx_init_early(void);
void am43xx_init_late(void);
@@ -163,6 +172,14 @@ static inline void omap3xxx_restart(enum reboot_mode mode, const char *cmd)
}
#endif
+#ifdef CONFIG_SOC_TI81XX
+void ti81xx_restart(enum reboot_mode mode, const char *cmd);
+#else
+static inline void ti81xx_restart(enum reboot_mode mode, const char *cmd)
+{
+}
+#endif
+
#if defined(CONFIG_ARCH_OMAP4) || defined(CONFIG_SOC_OMAP5) || \
defined(CONFIG_SOC_DRA7XX) || defined(CONFIG_SOC_AM43XX)
void omap44xx_restart(enum reboot_mode mode, const char *cmd);
@@ -211,6 +228,7 @@ extern struct device *omap2_get_iva_device(void);
extern struct device *omap2_get_l3_device(void);
extern struct device *omap4_get_dsp_device(void);
+unsigned int omap4_xlate_irq(unsigned int hwirq);
void omap_gic_of_init(void);
#ifdef CONFIG_CACHE_L2X0
@@ -249,6 +267,7 @@ extern void omap4_cpu_die(unsigned int cpu);
extern struct smp_operations omap4_smp_ops;
extern void omap5_secondary_startup(void);
+extern void omap5_secondary_hyp_startup(void);
#endif
#if defined(CONFIG_SMP) && defined(CONFIG_PM)
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h
index a3c013345c45..b8a487181210 100644
--- a/arch/arm/mach-omap2/control.h
+++ b/arch/arm/mach-omap2/control.h
@@ -53,6 +53,7 @@
#define OMAP343X_CONTROL_GENERAL_WKUP 0xa60
/* TI81XX spefic control submodules */
+#define TI81XX_CONTROL_DEVBOOT 0x040
#define TI81XX_CONTROL_DEVCONF 0x600
/* Control register offsets - read/write with omap_ctrl_{read,write}{bwl}() */
@@ -246,6 +247,9 @@
#define OMAP3_PADCONF_SAD2D_MSTANDBY 0x250
#define OMAP3_PADCONF_SAD2D_IDLEACK 0x254
+/* TI81XX CONTROL_DEVBOOT register offsets */
+#define TI81XX_CONTROL_STATUS (TI81XX_CONTROL_DEVBOOT + 0x000)
+
/* TI81XX CONTROL_DEVCONF register offsets */
#define TI81XX_CONTROL_DEVICE_ID (TI81XX_CONTROL_DEVCONF + 0x000)
@@ -286,6 +290,10 @@
#define OMAP5XXX_CONTROL_STATUS 0x134
#define OMAP5_DEVICETYPE_MASK (0x7 << 6)
+/* DRA7XX CONTROL CORE BOOTSTRAP */
+#define DRA7_CTRL_CORE_BOOTSTRAP 0x6c4
+#define DRA7_SPEEDSELECT_MASK (0x3 << 8)
+
/*
* REVISIT: This list of registers is not comprehensive - there are more
* that should be added.
diff --git a/arch/arm/mach-omap2/dpll44xx.c b/arch/arm/mach-omap2/dpll44xx.c
index 0e58e5a85d53..fc712240e5fd 100644
--- a/arch/arm/mach-omap2/dpll44xx.c
+++ b/arch/arm/mach-omap2/dpll44xx.c
@@ -36,26 +36,6 @@
/* Static rate multiplier for OMAP4 REGM4XEN clocks */
#define OMAP4430_REGM4XEN_MULT 4
-/* Supported only on OMAP4 */
-int omap4_dpllmx_gatectrl_read(struct clk_hw_omap *clk)
-{
- u32 v;
- u32 mask;
-
- if (!clk || !clk->clksel_reg)
- return -EINVAL;
-
- mask = clk->flags & CLOCK_CLKOUTX2 ?
- OMAP4430_DPLL_CLKOUTX2_GATE_CTRL_MASK :
- OMAP4430_DPLL_CLKOUT_GATE_CTRL_MASK;
-
- v = omap2_clk_readl(clk, clk->clksel_reg);
- v &= mask;
- v >>= __ffs(mask);
-
- return v;
-}
-
void omap4_dpllmx_allow_gatectrl(struct clk_hw_omap *clk)
{
u32 v;
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c
index c25feba05818..2a2f4d56e4c8 100644
--- a/arch/arm/mach-omap2/id.c
+++ b/arch/arm/mach-omap2/id.c
@@ -56,6 +56,8 @@ int omap_type(void)
if (cpu_is_omap24xx()) {
val = omap_ctrl_readl(OMAP24XX_CONTROL_STATUS);
+ } else if (cpu_is_ti81xx()) {
+ val = omap_ctrl_readl(TI81XX_CONTROL_STATUS);
} else if (soc_is_am33xx() || soc_is_am43xx()) {
val = omap_ctrl_readl(AM33XX_CONTROL_STATUS);
} else if (cpu_is_omap34xx()) {
diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
index a1bd6affb508..e60780f05374 100644
--- a/arch/arm/mach-omap2/io.c
+++ b/arch/arm/mach-omap2/io.c
@@ -492,27 +492,6 @@ void __init am35xx_init_early(void)
omap_clk_soc_init = am35xx_dt_clk_init;
}
-void __init ti81xx_init_early(void)
-{
- omap2_set_globals_tap(OMAP343X_CLASS,
- OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE));
- omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE),
- NULL);
- omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE));
- omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), NULL);
- omap3xxx_check_revision();
- ti81xx_check_features();
- omap3xxx_voltagedomains_init();
- omap3xxx_powerdomains_init();
- omap3xxx_clockdomains_init();
- omap3xxx_hwmod_init();
- omap_hwmod_init_postsetup();
- if (of_have_populated_dt())
- omap_clk_soc_init = ti81xx_dt_clk_init;
- else
- omap_clk_soc_init = omap3xxx_clk_init;
-}
-
void __init omap3_init_late(void)
{
omap_common_late_init();
@@ -551,11 +530,54 @@ void __init am35xx_init_late(void)
void __init ti81xx_init_late(void)
{
omap_common_late_init();
- omap3_pm_init();
omap2_clk_enable_autoidle_all();
}
#endif
+#ifdef CONFIG_SOC_TI81XX
+void __init ti814x_init_early(void)
+{
+ omap2_set_globals_tap(TI814X_CLASS,
+ OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE));
+ omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE),
+ NULL);
+ omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE));
+ omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), NULL);
+ omap3xxx_check_revision();
+ ti81xx_check_features();
+ am33xx_prm_init();
+ am33xx_cm_init();
+ omap3xxx_voltagedomains_init();
+ omap3xxx_powerdomains_init();
+ ti81xx_clockdomains_init();
+ ti81xx_hwmod_init();
+ omap_hwmod_init_postsetup();
+ if (of_have_populated_dt())
+ omap_clk_soc_init = ti81xx_dt_clk_init;
+}
+
+void __init ti816x_init_early(void)
+{
+ omap2_set_globals_tap(TI816X_CLASS,
+ OMAP2_L4_IO_ADDRESS(TI81XX_TAP_BASE));
+ omap2_set_globals_control(OMAP2_L4_IO_ADDRESS(TI81XX_CTRL_BASE),
+ NULL);
+ omap2_set_globals_prm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE));
+ omap2_set_globals_cm(OMAP2_L4_IO_ADDRESS(TI81XX_PRCM_BASE), NULL);
+ omap3xxx_check_revision();
+ ti81xx_check_features();
+ am33xx_prm_init();
+ am33xx_cm_init();
+ omap3xxx_voltagedomains_init();
+ omap3xxx_powerdomains_init();
+ ti81xx_clockdomains_init();
+ ti81xx_hwmod_init();
+ omap_hwmod_init_postsetup();
+ if (of_have_populated_dt())
+ omap_clk_soc_init = ti81xx_dt_clk_init;
+}
+#endif
+
#ifdef CONFIG_SOC_AM33XX
void __init am33xx_init_early(void)
{
diff --git a/arch/arm/mach-omap2/omap-headsmp.S b/arch/arm/mach-omap2/omap-headsmp.S
index 4993d4bfe9b2..6d1dffca6c7b 100644
--- a/arch/arm/mach-omap2/omap-headsmp.S
+++ b/arch/arm/mach-omap2/omap-headsmp.S
@@ -22,6 +22,7 @@
/* Physical address needed since MMU not enabled yet on secondary core */
#define AUX_CORE_BOOT0_PA 0x48281800
+#define API_HYP_ENTRY 0x102
/*
* OMAP5 specific entry point for secondary CPU to jump from ROM
@@ -41,6 +42,26 @@ wait: ldr r2, =AUX_CORE_BOOT0_PA @ read from AuxCoreBoot0
b secondary_startup
ENDPROC(omap5_secondary_startup)
/*
+ * Same as omap5_secondary_startup except we call into the ROM to
+ * enable HYP mode first. This is called instead of
+ * omap5_secondary_startup if the primary CPU was put into HYP mode by
+ * the boot loader.
+ */
+ENTRY(omap5_secondary_hyp_startup)
+wait_2: ldr r2, =AUX_CORE_BOOT0_PA @ read from AuxCoreBoot0
+ ldr r0, [r2]
+ mov r0, r0, lsr #5
+ mrc p15, 0, r4, c0, c0, 5
+ and r4, r4, #0x0f
+ cmp r0, r4
+ bne wait_2
+ ldr r12, =API_HYP_ENTRY
+ adr r0, hyp_boot
+ smc #0
+hyp_boot:
+ b secondary_startup
+ENDPROC(omap5_secondary_hyp_startup)
+/*
* OMAP4 specific entry point for secondary CPU to jump from ROM
* code. This routine also provides a holding flag into which
* secondary core is held until we're ready for it to initialise.
diff --git a/arch/arm/mach-omap2/omap-pm-noop.c b/arch/arm/mach-omap2/omap-pm-noop.c
index 6a3be2bebddb..a1ee8066958e 100644
--- a/arch/arm/mach-omap2/omap-pm-noop.c
+++ b/arch/arm/mach-omap2/omap-pm-noop.c
@@ -86,200 +86,10 @@ int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r)
return 0;
}
-int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
- long t)
-{
- if (!req_dev || !dev || t < -1) {
- WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
- return -EINVAL;
- }
-
- if (t == -1)
- pr_debug("OMAP PM: remove max device latency constraint: dev %s\n",
- dev_name(dev));
- else
- pr_debug("OMAP PM: add max device latency constraint: dev %s, t = %ld usec\n",
- dev_name(dev), t);
-
- /*
- * For current Linux, this needs to map the device to a
- * powerdomain, then go through the list of current max lat
- * constraints on that powerdomain and find the smallest. If
- * the latency constraint has changed, the code should
- * recompute the state to enter for the next powerdomain
- * state. Conceivably, this code should also determine
- * whether to actually disable the device clocks or not,
- * depending on how long it takes to re-enable the clocks.
- *
- * TI CDP code can call constraint_set here.
- */
-
- return 0;
-}
-
-int omap_pm_set_max_sdma_lat(struct device *dev, long t)
-{
- if (!dev || t < -1) {
- WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
- return -EINVAL;
- }
-
- if (t == -1)
- pr_debug("OMAP PM: remove max DMA latency constraint: dev %s\n",
- dev_name(dev));
- else
- pr_debug("OMAP PM: add max DMA latency constraint: dev %s, t = %ld usec\n",
- dev_name(dev), t);
-
- /*
- * For current Linux PM QOS params, this code should scan the
- * list of maximum CPU and DMA latencies and select the
- * smallest, then set cpu_dma_latency pm_qos_param
- * accordingly.
- *
- * For future Linux PM QOS params, with separate CPU and DMA
- * latency params, this code should just set the dma_latency param.
- *
- * TI CDP code can call constraint_set here.
- */
-
- return 0;
-}
-
-int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r)
-{
- if (!dev || !c || r < 0) {
- WARN(1, "OMAP PM: %s: invalid parameter(s)", __func__);
- return -EINVAL;
- }
-
- if (r == 0)
- pr_debug("OMAP PM: remove min clk rate constraint: dev %s\n",
- dev_name(dev));
- else
- pr_debug("OMAP PM: add min clk rate constraint: dev %s, rate = %ld Hz\n",
- dev_name(dev), r);
-
- /*
- * Code in a real implementation should keep track of these
- * constraints on the clock, and determine the highest minimum
- * clock rate. It should iterate over each OPP and determine
- * whether the OPP will result in a clock rate that would
- * satisfy this constraint (and any other PM constraint in effect
- * at that time). Once it finds the lowest-voltage OPP that
- * meets those conditions, it should switch to it, or return
- * an error if the code is not capable of doing so.
- */
-
- return 0;
-}
-
/*
* DSP Bridge-specific constraints
*/
-const struct omap_opp *omap_pm_dsp_get_opp_table(void)
-{
- pr_debug("OMAP PM: DSP request for OPP table\n");
-
- /*
- * Return DSP frequency table here: The final item in the
- * array should have .rate = .opp_id = 0.
- */
-
- return NULL;
-}
-
-void omap_pm_dsp_set_min_opp(u8 opp_id)
-{
- if (opp_id == 0) {
- WARN_ON(1);
- return;
- }
-
- pr_debug("OMAP PM: DSP requests minimum VDD1 OPP to be %d\n", opp_id);
-
- /*
- *
- * For l-o dev tree, our VDD1 clk is keyed on OPP ID, so we
- * can just test to see which is higher, the CPU's desired OPP
- * ID or the DSP's desired OPP ID, and use whichever is
- * highest.
- *
- * In CDP12.14+, the VDD1 OPP custom clock that controls the DSP
- * rate is keyed on MPU speed, not the OPP ID. So we need to
- * map the OPP ID to the MPU speed for use with clk_set_rate()
- * if it is higher than the current OPP clock rate.
- *
- */
-}
-
-
-u8 omap_pm_dsp_get_opp(void)
-{
- pr_debug("OMAP PM: DSP requests current DSP OPP ID\n");
-
- /*
- * For l-o dev tree, call clk_get_rate() on VDD1 OPP clock
- *
- * CDP12.14+:
- * Call clk_get_rate() on the OPP custom clock, map that to an
- * OPP ID using the tables defined in board-*.c/chip-*.c files.
- */
-
- return 0;
-}
-
-/*
- * CPUFreq-originated constraint
- *
- * In the future, this should be handled by custom OPP clocktype
- * functions.
- */
-
-struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void)
-{
- pr_debug("OMAP PM: CPUFreq request for frequency table\n");
-
- /*
- * Return CPUFreq frequency table here: loop over
- * all VDD1 clkrates, pull out the mpu_ck frequencies, build
- * table
- */
-
- return NULL;
-}
-
-void omap_pm_cpu_set_freq(unsigned long f)
-{
- if (f == 0) {
- WARN_ON(1);
- return;
- }
-
- pr_debug("OMAP PM: CPUFreq requests CPU frequency to be set to %lu\n",
- f);
-
- /*
- * For l-o dev tree, determine whether MPU freq or DSP OPP id
- * freq is higher. Find the OPP ID corresponding to the
- * higher frequency. Call clk_round_rate() and clk_set_rate()
- * on the OPP custom clock.
- *
- * CDP should just be able to set the VDD1 OPP clock rate here.
- */
-}
-
-unsigned long omap_pm_cpu_get_freq(void)
-{
- pr_debug("OMAP PM: CPUFreq requests current CPU frequency\n");
-
- /*
- * Call clk_get_rate() on the mpu_ck.
- */
-
- return 0;
-}
/**
* omap_pm_enable_off_mode - notify OMAP PM that off-mode is enabled
@@ -363,9 +173,3 @@ int __init omap_pm_if_init(void)
{
return 0;
}
-
-void omap_pm_if_exit(void)
-{
- /* Deallocate CPUFreq frequency table here */
-}
-
diff --git a/arch/arm/mach-omap2/omap-pm.h b/arch/arm/mach-omap2/omap-pm.h
index 1d777e63e05c..109bef5538eb 100644
--- a/arch/arm/mach-omap2/omap-pm.h
+++ b/arch/arm/mach-omap2/omap-pm.h
@@ -50,14 +50,6 @@ int __init omap_pm_if_early_init(void);
*/
int __init omap_pm_if_init(void);
-/**
- * omap_pm_if_exit - OMAP PM exit code
- *
- * Exit code; currently unused. The "_if_" is to avoid name
- * collisions with the PM idle-loop code.
- */
-void omap_pm_if_exit(void);
-
/*
* Device-driver-originated constraints (via board-*.c files, platform_data)
*/
@@ -132,163 +124,6 @@ int omap_pm_set_max_mpu_wakeup_lat(struct device *dev, long t);
int omap_pm_set_min_bus_tput(struct device *dev, u8 agent_id, unsigned long r);
-/**
- * omap_pm_set_max_dev_wakeup_lat - set the maximum device enable latency
- * @req_dev: struct device * requesting the constraint, or NULL if none
- * @dev: struct device * to set the constraint one
- * @t: maximum device wakeup latency in microseconds
- *
- * Request that the maximum amount of time necessary for a device @dev
- * to become accessible after its clocks are enabled should be no
- * greater than @t microseconds. Specifically, this represents the
- * time from when a device driver enables device clocks with
- * clk_enable(), to when the register reads and writes on the device
- * will succeed. This function should be called before clk_disable()
- * is called, since the power state transition decision may be made
- * during clk_disable().
- *
- * It is intended that underlying PM code will use this information to
- * determine what power state to put the powerdomain enclosing this
- * device into.
- *
- * Multiple calls to omap_pm_set_max_dev_wakeup_lat() will replace the
- * previous wakeup latency values for this device. To remove the
- * wakeup latency restriction for this device, call with t = -1.
- *
- * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
- * is not satisfiable, or 0 upon success.
- */
-int omap_pm_set_max_dev_wakeup_lat(struct device *req_dev, struct device *dev,
- long t);
-
-
-/**
- * omap_pm_set_max_sdma_lat - set the maximum system DMA transfer start latency
- * @dev: struct device *
- * @t: maximum DMA transfer start latency in microseconds
- *
- * Request that the maximum system DMA transfer start latency for this
- * device 'dev' should be no greater than 't' microseconds. "DMA
- * transfer start latency" here is defined as the elapsed time from
- * when a device (e.g., McBSP) requests that a system DMA transfer
- * start or continue, to the time at which data starts to flow into
- * that device from the system DMA controller.
- *
- * It is intended that underlying PM code will use this information to
- * determine what power state to put the CORE powerdomain into.
- *
- * Since system DMA transfers may not involve the MPU, this function
- * will not affect MPU wakeup latency. Use set_max_cpu_lat() to do
- * so. Similarly, this function will not affect device wakeup latency
- * -- use set_max_dev_wakeup_lat() to affect that.
- *
- * Multiple calls to set_max_sdma_lat() will replace the previous t
- * value for this device. To remove the maximum DMA latency for this
- * device, call with t = -1.
- *
- * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
- * is not satisfiable, or 0 upon success.
- */
-int omap_pm_set_max_sdma_lat(struct device *dev, long t);
-
-
-/**
- * omap_pm_set_min_clk_rate - set minimum clock rate requested by @dev
- * @dev: struct device * requesting the constraint
- * @clk: struct clk * to set the minimum rate constraint on
- * @r: minimum rate in Hz
- *
- * Request that the minimum clock rate on the device @dev's clk @clk
- * be no less than @r Hz.
- *
- * It is expected that the OMAP PM code will use this information to
- * find an OPP or clock setting that will satisfy this clock rate
- * constraint, along with any other applicable system constraints on
- * the clock rate or corresponding voltage, etc.
- *
- * omap_pm_set_min_clk_rate() differs from the clock code's
- * clk_set_rate() in that it considers other constraints before taking
- * any hardware action, and may change a system OPP rather than just a
- * clock rate. clk_set_rate() is intended to be a low-level
- * interface.
- *
- * omap_pm_set_min_clk_rate() is easily open to abuse. A better API
- * would be something like "omap_pm_set_min_dev_performance()";
- * however, there is no easily-generalizable concept of performance
- * that applies to all devices. Only a device (and possibly the
- * device subsystem) has both the subsystem-specific knowledge, and
- * the hardware IP block-specific knowledge, to translate a constraint
- * on "touchscreen sampling accuracy" or "number of pixels or polygons
- * rendered per second" to a clock rate. This translation can be
- * dependent on the hardware IP block's revision, or firmware version,
- * and the driver is the only code on the system that has this
- * information and can know how to translate that into a clock rate.
- *
- * The intended use-case for this function is for userspace or other
- * kernel code to communicate a particular performance requirement to
- * a subsystem; then for the subsystem to communicate that requirement
- * to something that is meaningful to the device driver; then for the
- * device driver to convert that requirement to a clock rate, and to
- * then call omap_pm_set_min_clk_rate().
- *
- * Users of this function (such as device drivers) should not simply
- * call this function with some high clock rate to ensure "high
- * performance." Rather, the device driver should take a performance
- * constraint from its subsystem, such as "render at least X polygons
- * per second," and use some formula or table to convert that into a
- * clock rate constraint given the hardware type and hardware
- * revision. Device drivers or subsystems should not assume that they
- * know how to make a power/performance tradeoff - some device use
- * cases may tolerate a lower-fidelity device function for lower power
- * consumption; others may demand a higher-fidelity device function,
- * no matter what the power consumption.
- *
- * Multiple calls to omap_pm_set_min_clk_rate() will replace the
- * previous rate value for the device @dev. To remove the minimum clock
- * rate constraint for the device, call with r = 0.
- *
- * Returns -EINVAL for an invalid argument, -ERANGE if the constraint
- * is not satisfiable, or 0 upon success.
- */
-int omap_pm_set_min_clk_rate(struct device *dev, struct clk *c, long r);
-
-/*
- * DSP Bridge-specific constraints
- */
-
-/**
- * omap_pm_dsp_get_opp_table - get OPP->DSP clock frequency table
- *
- * Intended for use by DSPBridge. Returns an array of OPP->DSP clock
- * frequency entries. The final item in the array should have .rate =
- * .opp_id = 0.
- */
-const struct omap_opp *omap_pm_dsp_get_opp_table(void);
-
-/**
- * omap_pm_dsp_set_min_opp - receive desired OPP target ID from DSP Bridge
- * @opp_id: target DSP OPP ID
- *
- * Set a minimum OPP ID for the DSP. This is intended to be called
- * only from the DSP Bridge MPU-side driver. Unfortunately, the only
- * information that code receives from the DSP/BIOS load estimator is the
- * target OPP ID; hence, this interface. No return value.
- */
-void omap_pm_dsp_set_min_opp(u8 opp_id);
-
-/**
- * omap_pm_dsp_get_opp - report the current DSP OPP ID
- *
- * Report the current OPP for the DSP. Since on OMAP3, the DSP and
- * MPU share a single voltage domain, the OPP ID returned back may
- * represent a higher DSP speed than the OPP requested via
- * omap_pm_dsp_set_min_opp().
- *
- * Returns the current VDD1 OPP ID, or 0 upon error.
- */
-u8 omap_pm_dsp_get_opp(void);
-
-
/*
* CPUFreq-originated constraint
*
@@ -296,33 +131,6 @@ u8 omap_pm_dsp_get_opp(void);
* functions.
*/
-/**
- * omap_pm_cpu_get_freq_table - return a cpufreq_frequency_table array ptr
- *
- * Provide a frequency table usable by CPUFreq for the current chip/board.
- * Returns a pointer to a struct cpufreq_frequency_table array or NULL
- * upon error.
- */
-struct cpufreq_frequency_table **omap_pm_cpu_get_freq_table(void);
-
-/**
- * omap_pm_cpu_set_freq - set the current minimum MPU frequency
- * @f: MPU frequency in Hz
- *
- * Set the current minimum CPU frequency. The actual CPU frequency
- * used could end up higher if the DSP requested a higher OPP.
- * Intended to be called by plat-omap/cpu_omap.c:omap_target(). No
- * return value.
- */
-void omap_pm_cpu_set_freq(unsigned long f);
-
-/**
- * omap_pm_cpu_get_freq - report the current CPU frequency
- *
- * Returns the current MPU frequency, or 0 upon error.
- */
-unsigned long omap_pm_cpu_get_freq(void);
-
/*
* Device context loss tracking
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c
index 256e84ef0f67..5305ec7341ec 100644
--- a/arch/arm/mach-omap2/omap-smp.c
+++ b/arch/arm/mach-omap2/omap-smp.c
@@ -22,6 +22,7 @@
#include <linux/irqchip/arm-gic.h>
#include <asm/smp_scu.h>
+#include <asm/virt.h>
#include "omap-secure.h"
#include "omap-wakeupgen.h"
@@ -227,8 +228,16 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus)
if (omap_secure_apis_support())
omap_auxcoreboot_addr(virt_to_phys(startup_addr));
else
- writel_relaxed(virt_to_phys(omap5_secondary_startup),
- base + OMAP_AUX_CORE_BOOT_1);
+ /*
+ * If the boot CPU is in HYP mode then start secondary
+ * CPU in HYP mode as well.
+ */
+ if ((__boot_cpu_mode & MODE_MASK) == HYP_MODE)
+ writel_relaxed(virt_to_phys(omap5_secondary_hyp_startup),
+ base + OMAP_AUX_CORE_BOOT_1);
+ else
+ writel_relaxed(virt_to_phys(omap5_secondary_startup),
+ base + OMAP_AUX_CORE_BOOT_1);
}
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index b7cb44abe49b..2418bdf28ca2 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -166,7 +166,7 @@ void __iomem *omap4_get_l2cache_base(void)
return l2cache_base;
}
-static void omap4_l2c310_write_sec(unsigned long val, unsigned reg)
+void omap4_l2c310_write_sec(unsigned long val, unsigned reg)
{
unsigned smc_op;
@@ -201,24 +201,10 @@ static void omap4_l2c310_write_sec(unsigned long val, unsigned reg)
int __init omap_l2_cache_init(void)
{
- u32 aux_ctrl;
-
/* Static mapping, never released */
l2cache_base = ioremap(OMAP44XX_L2CACHE_BASE, SZ_4K);
if (WARN_ON(!l2cache_base))
return -ENOMEM;
-
- /* 16-way associativity, parity disabled, way size - 64KB (es2.0 +) */
- aux_ctrl = L2C_AUX_CTRL_SHARED_OVERRIDE |
- L310_AUX_CTRL_DATA_PREFETCH |
- L310_AUX_CTRL_INSTR_PREFETCH;
-
- outer_cache.write_sec = omap4_l2c310_write_sec;
- if (of_have_populated_dt())
- l2x0_of_init(aux_ctrl, 0xcf9fffff);
- else
- l2x0_init(l2cache_base, aux_ctrl, 0xcf9fffff);
-
return 0;
}
#endif
@@ -256,6 +242,38 @@ static int __init omap4_sar_ram_init(void)
}
omap_early_initcall(omap4_sar_ram_init);
+static struct of_device_id gic_match[] = {
+ { .compatible = "arm,cortex-a9-gic", },
+ { .compatible = "arm,cortex-a15-gic", },
+ { },
+};
+
+static struct device_node *gic_node;
+
+unsigned int omap4_xlate_irq(unsigned int hwirq)
+{
+ struct of_phandle_args irq_data;
+ unsigned int irq;
+
+ if (!gic_node)
+ gic_node = of_find_matching_node(NULL, gic_match);
+
+ if (WARN_ON(!gic_node))
+ return hwirq;
+
+ irq_data.np = gic_node;
+ irq_data.args_count = 3;
+ irq_data.args[0] = 0;
+ irq_data.args[1] = hwirq - OMAP44XX_IRQ_GIC_START;
+ irq_data.args[2] = IRQ_TYPE_LEVEL_HIGH;
+
+ irq = irq_create_of_mapping(&irq_data);
+ if (WARN_ON(!irq))
+ irq = hwirq;
+
+ return irq;
+}
+
void __init omap_gic_of_init(void)
{
struct device_node *np;
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index cbb908dc5cf0..92afb723dcfc 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -2155,8 +2155,8 @@ static int _enable(struct omap_hwmod *oh)
if (soc_ops.disable_module)
soc_ops.disable_module(oh);
_disable_clocks(oh);
- pr_debug("omap_hwmod: %s: _wait_target_ready: %d\n",
- oh->name, r);
+ pr_err("omap_hwmod: %s: _wait_target_ready failed: %d\n",
+ oh->name, r);
if (oh->clkdm)
clkdm_hwmod_disable(oh->clkdm, oh);
@@ -3384,91 +3384,6 @@ int omap_hwmod_shutdown(struct omap_hwmod *oh)
return 0;
}
-/**
- * omap_hwmod_enable_clocks - enable main_clk, all interface clocks
- * @oh: struct omap_hwmod *oh
- *
- * Intended to be called by the omap_device code.
- */
-int omap_hwmod_enable_clocks(struct omap_hwmod *oh)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&oh->_lock, flags);
- _enable_clocks(oh);
- spin_unlock_irqrestore(&oh->_lock, flags);
-
- return 0;
-}
-
-/**
- * omap_hwmod_disable_clocks - disable main_clk, all interface clocks
- * @oh: struct omap_hwmod *oh
- *
- * Intended to be called by the omap_device code.
- */
-int omap_hwmod_disable_clocks(struct omap_hwmod *oh)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&oh->_lock, flags);
- _disable_clocks(oh);
- spin_unlock_irqrestore(&oh->_lock, flags);
-
- return 0;
-}
-
-/**
- * omap_hwmod_ocp_barrier - wait for posted writes against the hwmod to complete
- * @oh: struct omap_hwmod *oh
- *
- * Intended to be called by drivers and core code when all posted
- * writes to a device must complete before continuing further
- * execution (for example, after clearing some device IRQSTATUS
- * register bits)
- *
- * XXX what about targets with multiple OCP threads?
- */
-void omap_hwmod_ocp_barrier(struct omap_hwmod *oh)
-{
- BUG_ON(!oh);
-
- if (!oh->class->sysc || !oh->class->sysc->sysc_flags) {
- WARN(1, "omap_device: %s: OCP barrier impossible due to device configuration\n",
- oh->name);
- return;
- }
-
- /*
- * Forces posted writes to complete on the OCP thread handling
- * register writes
- */
- omap_hwmod_read(oh, oh->class->sysc->sysc_offs);
-}
-
-/**
- * omap_hwmod_reset - reset the hwmod
- * @oh: struct omap_hwmod *
- *
- * Under some conditions, a driver may wish to reset the entire device.
- * Called from omap_device code. Returns -EINVAL on error or passes along
- * the return value from _reset().
- */
-int omap_hwmod_reset(struct omap_hwmod *oh)
-{
- int r;
- unsigned long flags;
-
- if (!oh)
- return -EINVAL;
-
- spin_lock_irqsave(&oh->_lock, flags);
- r = _reset(oh);
- spin_unlock_irqrestore(&oh->_lock, flags);
-
- return r;
-}
-
/*
* IP block data retrieval functions
*/
@@ -3534,9 +3449,15 @@ int omap_hwmod_fill_resources(struct omap_hwmod *oh, struct resource *res)
mpu_irqs_cnt = _count_mpu_irqs(oh);
for (i = 0; i < mpu_irqs_cnt; i++) {
+ unsigned int irq;
+
+ if (oh->xlate_irq)
+ irq = oh->xlate_irq((oh->mpu_irqs + i)->irq);
+ else
+ irq = (oh->mpu_irqs + i)->irq;
(res + r)->name = (oh->mpu_irqs + i)->name;
- (res + r)->start = (oh->mpu_irqs + i)->irq;
- (res + r)->end = (oh->mpu_irqs + i)->irq;
+ (res + r)->start = irq;
+ (res + r)->end = irq;
(res + r)->flags = IORESOURCE_IRQ;
r++;
}
@@ -3723,52 +3644,12 @@ void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh)
return oh->_mpu_rt_va;
}
-/**
- * omap_hwmod_add_initiator_dep - add sleepdep from @init_oh to @oh
- * @oh: struct omap_hwmod *
- * @init_oh: struct omap_hwmod * (initiator)
- *
- * Add a sleep dependency between the initiator @init_oh and @oh.
- * Intended to be called by DSP/Bridge code via platform_data for the
- * DSP case; and by the DMA code in the sDMA case. DMA code, *Bridge
- * code needs to add/del initiator dependencies dynamically
- * before/after accessing a device. Returns the return value from
- * _add_initiator_dep().
- *
- * XXX Keep a usecount in the clockdomain code
- */
-int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
- struct omap_hwmod *init_oh)
-{
- return _add_initiator_dep(oh, init_oh);
-}
-
/*
* XXX what about functions for drivers to save/restore ocp_sysconfig
* for context save/restore operations?
*/
/**
- * omap_hwmod_del_initiator_dep - remove sleepdep from @init_oh to @oh
- * @oh: struct omap_hwmod *
- * @init_oh: struct omap_hwmod * (initiator)
- *
- * Remove a sleep dependency between the initiator @init_oh and @oh.
- * Intended to be called by DSP/Bridge code via platform_data for the
- * DSP case; and by the DMA code in the sDMA case. DMA code, *Bridge
- * code needs to add/del initiator dependencies dynamically
- * before/after accessing a device. Returns the return value from
- * _del_initiator_dep().
- *
- * XXX Keep a usecount in the clockdomain code
- */
-int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
- struct omap_hwmod *init_oh)
-{
- return _del_initiator_dep(oh, init_oh);
-}
-
-/**
* omap_hwmod_enable_wakeup - allow device to wake up the system
* @oh: struct omap_hwmod *
*
@@ -3889,33 +3770,6 @@ int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name)
}
/**
- * omap_hwmod_read_hardreset - read the HW reset line state of submodules
- * contained in the hwmod module
- * @oh: struct omap_hwmod *
- * @name: name of the reset line to look up and read
- *
- * Return the current state of the hwmod @oh's reset line named @name:
- * returns -EINVAL upon parameter error or if this operation
- * is unsupported on the current OMAP; otherwise, passes along the return
- * value from _read_hardreset().
- */
-int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name)
-{
- int ret;
- unsigned long flags;
-
- if (!oh)
- return -EINVAL;
-
- spin_lock_irqsave(&oh->_lock, flags);
- ret = _read_hardreset(oh, name);
- spin_unlock_irqrestore(&oh->_lock, flags);
-
- return ret;
-}
-
-
-/**
* omap_hwmod_for_each_by_class - call @fn for each hwmod of class @classname
* @classname: struct omap_hwmod_class name to search for
* @fn: callback function pointer to call for each hwmod in class @classname
@@ -4025,86 +3879,6 @@ int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh)
}
/**
- * omap_hwmod_no_setup_reset - prevent a hwmod from being reset upon setup
- * @oh: struct omap_hwmod *
- *
- * Prevent the hwmod @oh from being reset during the setup process.
- * Intended for use by board-*.c files on boards with devices that
- * cannot tolerate being reset. Must be called before the hwmod has
- * been set up. Returns 0 upon success or negative error code upon
- * failure.
- */
-int omap_hwmod_no_setup_reset(struct omap_hwmod *oh)
-{
- if (!oh)
- return -EINVAL;
-
- if (oh->_state != _HWMOD_STATE_REGISTERED) {
- pr_err("omap_hwmod: %s: cannot prevent setup reset; in wrong state\n",
- oh->name);
- return -EINVAL;
- }
-
- oh->flags |= HWMOD_INIT_NO_RESET;
-
- return 0;
-}
-
-/**
- * omap_hwmod_pad_route_irq - route an I/O pad wakeup to a particular MPU IRQ
- * @oh: struct omap_hwmod * containing hwmod mux entries
- * @pad_idx: array index in oh->mux of the hwmod mux entry to route wakeup
- * @irq_idx: the hwmod mpu_irqs array index of the IRQ to trigger on wakeup
- *
- * When an I/O pad wakeup arrives for the dynamic or wakeup hwmod mux
- * entry number @pad_idx for the hwmod @oh, trigger the interrupt
- * service routine for the hwmod's mpu_irqs array index @irq_idx. If
- * this function is not called for a given pad_idx, then the ISR
- * associated with @oh's first MPU IRQ will be triggered when an I/O
- * pad wakeup occurs on that pad. Note that @pad_idx is the index of
- * the _dynamic or wakeup_ entry: if there are other entries not
- * marked with OMAP_DEVICE_PAD_WAKEUP or OMAP_DEVICE_PAD_REMUX, these
- * entries are NOT COUNTED in the dynamic pad index. This function
- * must be called separately for each pad that requires its interrupt
- * to be re-routed this way. Returns -EINVAL if there is an argument
- * problem or if @oh does not have hwmod mux entries or MPU IRQs;
- * returns -ENOMEM if memory cannot be allocated; or 0 upon success.
- *
- * XXX This function interface is fragile. Rather than using array
- * indexes, which are subject to unpredictable change, it should be
- * using hwmod IRQ names, and some other stable key for the hwmod mux
- * pad records.
- */
-int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx)
-{
- int nr_irqs;
-
- might_sleep();
-
- if (!oh || !oh->mux || !oh->mpu_irqs || pad_idx < 0 ||
- pad_idx >= oh->mux->nr_pads_dynamic)
- return -EINVAL;
-
- /* Check the number of available mpu_irqs */
- for (nr_irqs = 0; oh->mpu_irqs[nr_irqs].irq >= 0; nr_irqs++)
- ;
-
- if (irq_idx >= nr_irqs)
- return -EINVAL;
-
- if (!oh->mux->irqs) {
- /* XXX What frees this? */
- oh->mux->irqs = kzalloc(sizeof(int) * oh->mux->nr_pads_dynamic,
- GFP_KERNEL);
- if (!oh->mux->irqs)
- return -ENOMEM;
- }
- oh->mux->irqs[pad_idx] = irq_idx;
-
- return 0;
-}
-
-/**
* omap_hwmod_init - initialize the hwmod code
*
* Sets up some function pointers needed by the hwmod code to operate on the
@@ -4142,7 +3916,7 @@ void __init omap_hwmod_init(void)
soc_ops.deassert_hardreset = _omap4_deassert_hardreset;
soc_ops.is_hardreset_asserted = _omap4_is_hardreset_asserted;
soc_ops.init_clkdm = _init_clkdm;
- } else if (soc_is_am33xx()) {
+ } else if (cpu_is_ti816x() || soc_is_am33xx()) {
soc_ops.enable_module = _omap4_enable_module;
soc_ops.disable_module = _omap4_disable_module;
soc_ops.wait_target_ready = _omap4_wait_target_ready;
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h
index 35ca6efbec31..9d4bec6ee742 100644
--- a/arch/arm/mach-omap2/omap_hwmod.h
+++ b/arch/arm/mach-omap2/omap_hwmod.h
@@ -676,6 +676,7 @@ struct omap_hwmod {
spinlock_t _lock;
struct list_head node;
struct omap_hwmod_ocp_if *_mpu_port;
+ unsigned int (*xlate_irq)(unsigned int);
u16 flags;
u8 mpu_rt_idx;
u8 response_lat;
@@ -702,13 +703,6 @@ int omap_hwmod_shutdown(struct omap_hwmod *oh);
int omap_hwmod_assert_hardreset(struct omap_hwmod *oh, const char *name);
int omap_hwmod_deassert_hardreset(struct omap_hwmod *oh, const char *name);
-int omap_hwmod_read_hardreset(struct omap_hwmod *oh, const char *name);
-
-int omap_hwmod_enable_clocks(struct omap_hwmod *oh);
-int omap_hwmod_disable_clocks(struct omap_hwmod *oh);
-
-int omap_hwmod_reset(struct omap_hwmod *oh);
-void omap_hwmod_ocp_barrier(struct omap_hwmod *oh);
void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs);
u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs);
@@ -723,11 +717,6 @@ int omap_hwmod_get_resource_byname(struct omap_hwmod *oh, unsigned int type,
struct powerdomain *omap_hwmod_get_pwrdm(struct omap_hwmod *oh);
void __iomem *omap_hwmod_get_mpu_rt_va(struct omap_hwmod *oh);
-int omap_hwmod_add_initiator_dep(struct omap_hwmod *oh,
- struct omap_hwmod *init_oh);
-int omap_hwmod_del_initiator_dep(struct omap_hwmod *oh,
- struct omap_hwmod *init_oh);
-
int omap_hwmod_enable_wakeup(struct omap_hwmod *oh);
int omap_hwmod_disable_wakeup(struct omap_hwmod *oh);
@@ -739,10 +728,6 @@ int omap_hwmod_for_each_by_class(const char *classname,
int omap_hwmod_set_postsetup_state(struct omap_hwmod *oh, u8 state);
int omap_hwmod_get_context_loss_count(struct omap_hwmod *oh);
-int omap_hwmod_no_setup_reset(struct omap_hwmod *oh);
-
-int omap_hwmod_pad_route_irq(struct omap_hwmod *oh, int pad_idx, int irq_idx);
-
extern void __init omap_hwmod_init(void);
const char *omap_hwmod_get_main_clk(struct omap_hwmod *oh);
@@ -763,6 +748,7 @@ extern int omap3xxx_hwmod_init(void);
extern int omap44xx_hwmod_init(void);
extern int omap54xx_hwmod_init(void);
extern int am33xx_hwmod_init(void);
+extern int ti81xx_hwmod_init(void);
extern int dra7xx_hwmod_init(void);
int am43xx_hwmod_init(void);
diff --git a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
index 11468eea3871..4e8e93c398db 100644
--- a/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_3xxx_data.c
@@ -29,8 +29,6 @@
#include <linux/platform_data/mailbox-omap.h>
#include <plat/dmtimer.h>
-#include "am35xx.h"
-
#include "soc.h"
#include "omap_hwmod.h"
#include "omap_hwmod_common_data.h"
@@ -50,6 +48,8 @@
* elsewhere.
*/
+#define AM35XX_IPSS_USBOTGSS_BASE 0x5C040000
+
/*
* IP blocks
*/
@@ -3459,15 +3459,6 @@ static struct omap_hwmod_ocp_if am35xx_mdio__l3 = {
.user = OCP_USER_MPU,
};
-static struct omap_hwmod_addr_space am35xx_mdio_addrs[] = {
- {
- .pa_start = AM35XX_IPSS_MDIO_BASE,
- .pa_end = AM35XX_IPSS_MDIO_BASE + SZ_4K - 1,
- .flags = ADDR_TYPE_RT,
- },
- { }
-};
-
/* l4_core -> davinci mdio */
/*
* XXX Should be connected to an IPSS hwmod, not the L4_CORE directly;
@@ -3478,25 +3469,15 @@ static struct omap_hwmod_ocp_if am35xx_l4_core__mdio = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &am35xx_mdio_hwmod,
.clk = "emac_fck",
- .addr = am35xx_mdio_addrs,
.user = OCP_USER_MPU,
};
-static struct omap_hwmod_irq_info am35xx_emac_mpu_irqs[] = {
- { .name = "rxthresh", .irq = 67 + OMAP_INTC_START, },
- { .name = "rx_pulse", .irq = 68 + OMAP_INTC_START, },
- { .name = "tx_pulse", .irq = 69 + OMAP_INTC_START },
- { .name = "misc_pulse", .irq = 70 + OMAP_INTC_START },
- { .irq = -1 },
-};
-
static struct omap_hwmod_class am35xx_emac_class = {
.name = "davinci_emac",
};
static struct omap_hwmod am35xx_emac_hwmod = {
.name = "davinci_emac",
- .mpu_irqs = am35xx_emac_mpu_irqs,
.class = &am35xx_emac_class,
/*
* According to Mark Greer, the MPU will not return from WFI
@@ -3519,15 +3500,6 @@ static struct omap_hwmod_ocp_if am35xx_emac__l3 = {
.user = OCP_USER_MPU,
};
-static struct omap_hwmod_addr_space am35xx_emac_addrs[] = {
- {
- .pa_start = AM35XX_IPSS_EMAC_BASE,
- .pa_end = AM35XX_IPSS_EMAC_BASE + 0x30000 - 1,
- .flags = ADDR_TYPE_RT,
- },
- { }
-};
-
/* l4_core -> davinci emac */
/*
* XXX Should be connected to an IPSS hwmod, not the L4_CORE directly;
@@ -3538,7 +3510,6 @@ static struct omap_hwmod_ocp_if am35xx_l4_core__emac = {
.master = &omap3xxx_l4_core_hwmod,
.slave = &am35xx_emac_hwmod,
.clk = "emac_ick",
- .addr = am35xx_emac_addrs,
.user = OCP_USER_MPU,
};
diff --git a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
index 5c6c8410160e..8eb85925e444 100644
--- a/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_43xx_data.c
@@ -498,6 +498,7 @@ static struct omap_hwmod am43xx_dss_dispc_hwmod = {
},
},
.dev_attr = &am43xx_dss_dispc_dev_attr,
+ .parent_hwmod = &am43xx_dss_core_hwmod,
};
/* rfbi */
@@ -512,6 +513,7 @@ static struct omap_hwmod am43xx_dss_rfbi_hwmod = {
.clkctrl_offs = AM43XX_CM_PER_DSS_CLKCTRL_OFFSET,
},
},
+ .parent_hwmod = &am43xx_dss_core_hwmod,
};
/* Interfaces */
diff --git a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
index c314b3c31117..f5e68a782025 100644
--- a/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_44xx_data.c
@@ -479,6 +479,7 @@ static struct omap_hwmod omap44xx_dma_system_hwmod = {
.class = &omap44xx_dma_hwmod_class,
.clkdm_name = "l3_dma_clkdm",
.mpu_irqs = omap44xx_dma_system_irqs,
+ .xlate_irq = omap4_xlate_irq,
.main_clk = "l3_div_ck",
.prcm = {
.omap4 = {
@@ -640,6 +641,7 @@ static struct omap_hwmod omap44xx_dss_dispc_hwmod = {
.class = &omap44xx_dispc_hwmod_class,
.clkdm_name = "l3_dss_clkdm",
.mpu_irqs = omap44xx_dss_dispc_irqs,
+ .xlate_irq = omap4_xlate_irq,
.sdma_reqs = omap44xx_dss_dispc_sdma_reqs,
.main_clk = "dss_dss_clk",
.prcm = {
@@ -693,6 +695,7 @@ static struct omap_hwmod omap44xx_dss_dsi1_hwmod = {
.class = &omap44xx_dsi_hwmod_class,
.clkdm_name = "l3_dss_clkdm",
.mpu_irqs = omap44xx_dss_dsi1_irqs,
+ .xlate_irq = omap4_xlate_irq,
.sdma_reqs = omap44xx_dss_dsi1_sdma_reqs,
.main_clk = "dss_dss_clk",
.prcm = {
@@ -726,6 +729,7 @@ static struct omap_hwmod omap44xx_dss_dsi2_hwmod = {
.class = &omap44xx_dsi_hwmod_class,
.clkdm_name = "l3_dss_clkdm",
.mpu_irqs = omap44xx_dss_dsi2_irqs,
+ .xlate_irq = omap4_xlate_irq,
.sdma_reqs = omap44xx_dss_dsi2_sdma_reqs,
.main_clk = "dss_dss_clk",
.prcm = {
@@ -784,6 +788,7 @@ static struct omap_hwmod omap44xx_dss_hdmi_hwmod = {
*/
.flags = HWMOD_SWSUP_SIDLE,
.mpu_irqs = omap44xx_dss_hdmi_irqs,
+ .xlate_irq = omap4_xlate_irq,
.sdma_reqs = omap44xx_dss_hdmi_sdma_reqs,
.main_clk = "dss_48mhz_clk",
.prcm = {
diff --git a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
index 3e9523084b2a..7c3fac035e93 100644
--- a/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_54xx_data.c
@@ -288,6 +288,7 @@ static struct omap_hwmod omap54xx_dma_system_hwmod = {
.class = &omap54xx_dma_hwmod_class,
.clkdm_name = "dma_clkdm",
.mpu_irqs = omap54xx_dma_system_irqs,
+ .xlate_irq = omap4_xlate_irq,
.main_clk = "l3_iclk_div",
.prcm = {
.omap4 = {
diff --git a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
index ffd6604cd546..e8692e7675b8 100644
--- a/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
+++ b/arch/arm/mach-omap2/omap_hwmod_7xx_data.c
@@ -819,7 +819,8 @@ static struct omap_hwmod dra7xx_gpmc_hwmod = {
.name = "gpmc",
.class = &dra7xx_gpmc_hwmod_class,
.clkdm_name = "l3main1_clkdm",
- .flags = HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET,
+ .flags = (HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET |
+ HWMOD_SWSUP_SIDLE),
.main_clk = "l3_iclk_div",
.prcm = {
.omap4 = {
@@ -2017,7 +2018,7 @@ static struct omap_hwmod dra7xx_uart3_hwmod = {
.class = &dra7xx_uart_hwmod_class,
.clkdm_name = "l4per_clkdm",
.main_clk = "uart3_gfclk_mux",
- .flags = HWMOD_SWSUP_SIDLE_ACT,
+ .flags = HWMOD_SWSUP_SIDLE_ACT | DEBUG_OMAP4UART3_FLAGS,
.prcm = {
.omap4 = {
.clkctrl_offs = DRA7XX_CM_L4PER_UART3_CLKCTRL_OFFSET,
diff --git a/arch/arm/mach-omap2/omap_hwmod_81xx_data.c b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
new file mode 100644
index 000000000000..cab1eb61ac96
--- /dev/null
+++ b/arch/arm/mach-omap2/omap_hwmod_81xx_data.c
@@ -0,0 +1,1136 @@
+/*
+ * DM81xx hwmod data.
+ *
+ * Copyright (C) 2010 Texas Instruments, Inc. - http://www.ti.com/
+ * Copyright (C) 2013 SKTB SKiT, http://www.skitlab.ru/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/platform_data/gpio-omap.h>
+#include <linux/platform_data/hsmmc-omap.h>
+#include <linux/platform_data/spi-omap2-mcspi.h>
+#include <plat/dmtimer.h>
+
+#include "omap_hwmod_common_data.h"
+#include "cm81xx.h"
+#include "ti81xx.h"
+#include "wd_timer.h"
+
+/*
+ * DM816X hardware modules integration data
+ *
+ * Note: This is incomplete and at present, not generated from h/w database.
+ */
+
+/*
+ * The alwon .clkctrl_offs field is offset from the CM_ALWON, that's
+ * TRM 18.7.17 CM_ALWON device register values minus 0x1400.
+ */
+#define DM816X_DM_ALWON_BASE 0x1400
+#define DM816X_CM_ALWON_MCASP0_CLKCTRL (0x1540 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MCASP1_CLKCTRL (0x1544 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MCASP2_CLKCTRL (0x1548 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MCBSP_CLKCTRL (0x154c - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_UART_0_CLKCTRL (0x1550 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_UART_1_CLKCTRL (0x1554 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_UART_2_CLKCTRL (0x1558 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_GPIO_0_CLKCTRL (0x155c - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_GPIO_1_CLKCTRL (0x1560 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_I2C_0_CLKCTRL (0x1564 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_I2C_1_CLKCTRL (0x1568 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_1_CLKCTRL (0x1570 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_2_CLKCTRL (0x1574 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_3_CLKCTRL (0x1578 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_4_CLKCTRL (0x157c - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_5_CLKCTRL (0x1580 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_6_CLKCTRL (0x1584 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TIMER_7_CLKCTRL (0x1588 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_WDTIMER_CLKCTRL (0x158c - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_SPI_CLKCTRL (0x1590 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MAILBOX_CLKCTRL (0x1594 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_SPINBOX_CLKCTRL (0x1598 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MMUDATA_CLKCTRL (0x159c - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MMUCFG_CLKCTRL (0x15a8 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_SDIO_CLKCTRL (0x15b0 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_OCMC_0_CLKCTRL (0x15b4 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_OCMC_1_CLKCTRL (0x15b8 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_CONTRL_CLKCTRL (0x15c4 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_GPMC_CLKCTRL (0x15d0 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_ETHERNET_0_CLKCTRL (0x15d4 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_ETHERNET_1_CLKCTRL (0x15d8 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_MPU_CLKCTRL (0x15dc - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_L3_CLKCTRL (0x15e4 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_L4HS_CLKCTRL (0x15e8 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_L4LS_CLKCTRL (0x15ec - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_RTC_CLKCTRL (0x15f0 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TPCC_CLKCTRL (0x15f4 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TPTC0_CLKCTRL (0x15f8 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TPTC1_CLKCTRL (0x15fc - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TPTC2_CLKCTRL (0x1600 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_TPTC3_CLKCTRL (0x1604 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_SR_0_CLKCTRL (0x1608 - DM816X_DM_ALWON_BASE)
+#define DM816X_CM_ALWON_SR_1_CLKCTRL (0x160c - DM816X_DM_ALWON_BASE)
+
+/*
+ * The default .clkctrl_offs field is offset from CM_DEFAULT, that's
+ * TRM 18.7.6 CM_DEFAULT device register values minus 0x500
+ */
+#define DM816X_CM_DEFAULT_OFFSET 0x500
+#define DM816X_CM_DEFAULT_USB_CLKCTRL (0x558 - DM816X_CM_DEFAULT_OFFSET)
+
+/* L3 Interconnect entries clocked at 125, 250 and 500MHz */
+static struct omap_hwmod dm816x_alwon_l3_slow_hwmod = {
+ .name = "alwon_l3_slow",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &l3_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+static struct omap_hwmod dm816x_default_l3_slow_hwmod = {
+ .name = "default_l3_slow",
+ .clkdm_name = "default_l3_slow_clkdm",
+ .class = &l3_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+static struct omap_hwmod dm816x_alwon_l3_med_hwmod = {
+ .name = "l3_med",
+ .clkdm_name = "alwon_l3_med_clkdm",
+ .class = &l3_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+static struct omap_hwmod dm816x_alwon_l3_fast_hwmod = {
+ .name = "l3_fast",
+ .clkdm_name = "alwon_l3_fast_clkdm",
+ .class = &l3_hwmod_class,
+ .flags = HWMOD_NO_IDLEST,
+};
+
+/*
+ * L4 standard peripherals, see TRM table 1-12 for devices using this.
+ * See TRM table 1-73 for devices using the 125MHz SYSCLK6 clock.
+ */
+static struct omap_hwmod dm816x_l4_ls_hwmod = {
+ .name = "l4_ls",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &l4_hwmod_class,
+};
+
+/*
+ * L4 high-speed peripherals. For devices using this, please see the TRM
+ * table 1-13. On dm816x, only EMAC, MDIO and SATA use this. See also TRM
+ * table 1-73 for devices using 250MHz SYSCLK5 clock.
+ */
+static struct omap_hwmod dm816x_l4_hs_hwmod = {
+ .name = "l4_hs",
+ .clkdm_name = "alwon_l3_med_clkdm",
+ .class = &l4_hwmod_class,
+};
+
+/* L3 slow -> L4 ls peripheral interface running at 125MHz */
+static struct omap_hwmod_ocp_if dm816x_alwon_l3_slow__l4_ls = {
+ .master = &dm816x_alwon_l3_slow_hwmod,
+ .slave = &dm816x_l4_ls_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+/* L3 med -> L4 fast peripheral interface running at 250MHz */
+static struct omap_hwmod_ocp_if dm816x_alwon_l3_slow__l4_hs = {
+ .master = &dm816x_alwon_l3_med_hwmod,
+ .slave = &dm816x_l4_hs_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+/* MPU */
+static struct omap_hwmod dm816x_mpu_hwmod = {
+ .name = "mpu",
+ .clkdm_name = "alwon_mpu_clkdm",
+ .class = &mpu_hwmod_class,
+ .flags = HWMOD_INIT_NO_IDLE,
+ .main_clk = "mpu_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_MPU_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod_ocp_if dm816x_mpu__alwon_l3_slow = {
+ .master = &dm816x_mpu_hwmod,
+ .slave = &dm816x_alwon_l3_slow_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+/* L3 med peripheral interface running at 250MHz */
+static struct omap_hwmod_ocp_if dm816x_mpu__alwon_l3_med = {
+ .master = &dm816x_mpu_hwmod,
+ .slave = &dm816x_alwon_l3_med_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+/* UART common */
+static struct omap_hwmod_class_sysconfig uart_sysc = {
+ .rev_offs = 0x50,
+ .sysc_offs = 0x54,
+ .syss_offs = 0x58,
+ .sysc_flags = SYSC_HAS_ENAWAKEUP | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE |
+ SYSS_HAS_RESET_STATUS,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ MSTANDBY_SMART_WKUP,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class uart_class = {
+ .name = "uart",
+ .sysc = &uart_sysc,
+};
+
+static struct omap_hwmod dm816x_uart1_hwmod = {
+ .name = "uart1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_UART_0_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &uart_class,
+ .flags = DEBUG_TI81XXUART1_FLAGS,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__uart1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_uart1_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_uart2_hwmod = {
+ .name = "uart2",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_UART_1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &uart_class,
+ .flags = DEBUG_TI81XXUART2_FLAGS,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__uart2 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_uart2_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_uart3_hwmod = {
+ .name = "uart3",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_UART_2_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &uart_class,
+ .flags = DEBUG_TI81XXUART3_FLAGS,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__uart3 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_uart3_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig wd_timer_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x10,
+ .syss_offs = 0x14,
+ .sysc_flags = SYSC_HAS_EMUFREE | SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class wd_timer_class = {
+ .name = "wd_timer",
+ .sysc = &wd_timer_sysc,
+ .pre_shutdown = &omap2_wd_timer_disable,
+ .reset = &omap2_wd_timer_reset,
+};
+
+static struct omap_hwmod dm816x_wd_timer_hwmod = {
+ .name = "wd_timer",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk18_ck",
+ .flags = HWMOD_NO_IDLEST,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_WDTIMER_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &wd_timer_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__wd_timer1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_wd_timer_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* I2C common */
+static struct omap_hwmod_class_sysconfig i2c_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x10,
+ .syss_offs = 0x90,
+ .sysc_flags = SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class i2c_class = {
+ .name = "i2c",
+ .sysc = &i2c_sysc,
+};
+
+static struct omap_hwmod dm81xx_i2c1_hwmod = {
+ .name = "i2c1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_I2C_0_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &i2c_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__i2c1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm81xx_i2c1_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_i2c2_hwmod = {
+ .name = "i2c2",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_I2C_1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &i2c_class,
+};
+
+static struct omap_hwmod_class_sysconfig dm81xx_elm_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__i2c2 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_i2c2_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class dm81xx_elm_hwmod_class = {
+ .name = "elm",
+ .sysc = &dm81xx_elm_sysc,
+};
+
+static struct omap_hwmod dm81xx_elm_hwmod = {
+ .name = "elm",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &dm81xx_elm_hwmod_class,
+ .main_clk = "sysclk6_ck",
+};
+
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__elm = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm81xx_elm_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig dm81xx_gpio_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0114,
+ .sysc_flags = SYSC_HAS_AUTOIDLE | SYSC_HAS_ENAWAKEUP |
+ SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSS_HAS_RESET_STATUS,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class dm81xx_gpio_hwmod_class = {
+ .name = "gpio",
+ .sysc = &dm81xx_gpio_sysc,
+ .rev = 2,
+};
+
+static struct omap_gpio_dev_attr gpio_dev_attr = {
+ .bank_width = 32,
+ .dbck_flag = true,
+};
+
+static struct omap_hwmod_opt_clk gpio1_opt_clks[] = {
+ { .role = "dbclk", .clk = "sysclk18_ck" },
+};
+
+static struct omap_hwmod dm81xx_gpio1_hwmod = {
+ .name = "gpio1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &dm81xx_gpio_hwmod_class,
+ .main_clk = "sysclk6_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_GPIO_0_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = gpio1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio1_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__gpio1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm81xx_gpio1_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_opt_clk gpio2_opt_clks[] = {
+ { .role = "dbclk", .clk = "sysclk18_ck" },
+};
+
+static struct omap_hwmod dm81xx_gpio2_hwmod = {
+ .name = "gpio2",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &dm81xx_gpio_hwmod_class,
+ .main_clk = "sysclk6_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_GPIO_1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .opt_clks = gpio2_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(gpio2_opt_clks),
+ .dev_attr = &gpio_dev_attr,
+};
+
+static struct omap_hwmod_ocp_if dm81xx_l4_ls__gpio2 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm81xx_gpio2_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig dm81xx_gpmc_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x10,
+ .syss_offs = 0x14,
+ .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class dm81xx_gpmc_hwmod_class = {
+ .name = "gpmc",
+ .sysc = &dm81xx_gpmc_sysc,
+};
+
+static struct omap_hwmod dm81xx_gpmc_hwmod = {
+ .name = "gpmc",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &dm81xx_gpmc_hwmod_class,
+ .main_clk = "sysclk6_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_GPMC_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm81xx_alwon_l3_slow__gpmc = {
+ .master = &dm816x_alwon_l3_slow_hwmod,
+ .slave = &dm81xx_gpmc_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig dm81xx_usbhsotg_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x10,
+ .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_MIDLEMODE |
+ SYSC_HAS_SOFTRESET,
+ .idlemodes = SIDLE_SMART | MSTANDBY_FORCE | MSTANDBY_SMART,
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class dm81xx_usbotg_class = {
+ .name = "usbotg",
+ .sysc = &dm81xx_usbhsotg_sysc,
+};
+
+static struct omap_hwmod dm81xx_usbss_hwmod = {
+ .name = "usb_otg_hs",
+ .clkdm_name = "default_l3_slow_clkdm",
+ .main_clk = "sysclk6_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_DEFAULT_USB_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &dm81xx_usbotg_class,
+};
+
+static struct omap_hwmod_ocp_if dm81xx_default_l3_slow__usbss = {
+ .master = &dm816x_default_l3_slow_hwmod,
+ .slave = &dm81xx_usbss_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig dm816x_timer_sysc = {
+ .rev_offs = 0x0000,
+ .sysc_offs = 0x0010,
+ .syss_offs = 0x0014,
+ .sysc_flags = SYSC_HAS_SIDLEMODE | SYSC_HAS_SOFTRESET,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART |
+ SIDLE_SMART_WKUP,
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class dm816x_timer_hwmod_class = {
+ .name = "timer",
+ .sysc = &dm816x_timer_sysc,
+};
+
+static struct omap_timer_capability_dev_attr capability_alwon_dev_attr = {
+ .timer_capability = OMAP_TIMER_ALWON,
+};
+
+static struct omap_hwmod dm816x_timer1_hwmod = {
+ .name = "timer1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer1_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer1_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_timer2_hwmod = {
+ .name = "timer2",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer2_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_2_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer2 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer2_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_timer3_hwmod = {
+ .name = "timer3",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer3_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_3_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer3 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer3_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_timer4_hwmod = {
+ .name = "timer4",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer4_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_4_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer4 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer4_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_timer5_hwmod = {
+ .name = "timer5",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer5_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_5_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer5 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer5_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_timer6_hwmod = {
+ .name = "timer6",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer6_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_6_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer6 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer6_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_timer7_hwmod = {
+ .name = "timer7",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "timer7_fck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TIMER_7_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &capability_alwon_dev_attr,
+ .class = &dm816x_timer_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__timer7 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_timer7_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+/* EMAC Ethernet */
+static struct omap_hwmod_class_sysconfig dm816x_emac_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x4,
+ .sysc_flags = SYSC_HAS_SOFTRESET,
+ .sysc_fields = &omap_hwmod_sysc_type2,
+};
+
+static struct omap_hwmod_class dm816x_emac_hwmod_class = {
+ .name = "emac",
+ .sysc = &dm816x_emac_sysc,
+};
+
+/*
+ * On dm816x the MDIO is within EMAC0. As the MDIO driver is a separate
+ * driver probed before EMAC0, we let MDIO do the clock idling.
+ */
+static struct omap_hwmod dm816x_emac0_hwmod = {
+ .name = "emac0",
+ .clkdm_name = "alwon_ethernet_clkdm",
+ .class = &dm816x_emac_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_hs__emac0 = {
+ .master = &dm816x_l4_hs_hwmod,
+ .slave = &dm816x_emac0_hwmod,
+ .clk = "sysclk5_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class dm816x_mdio_hwmod_class = {
+ .name = "davinci_mdio",
+ .sysc = &dm816x_emac_sysc,
+};
+
+struct omap_hwmod dm816x_emac0_mdio_hwmod = {
+ .name = "davinci_mdio",
+ .class = &dm816x_mdio_hwmod_class,
+ .clkdm_name = "alwon_ethernet_clkdm",
+ .main_clk = "sysclk24_ck",
+ .flags = HWMOD_NO_IDLEST,
+ /*
+ * REVISIT: This should be moved to the emac0_hwmod
+ * once we have a better way to handle device slaves.
+ */
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_ETHERNET_0_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm816x_emac0__mdio = {
+ .master = &dm816x_l4_hs_hwmod,
+ .slave = &dm816x_emac0_mdio_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod dm816x_emac1_hwmod = {
+ .name = "emac1",
+ .clkdm_name = "alwon_ethernet_clkdm",
+ .main_clk = "sysclk24_ck",
+ .flags = HWMOD_NO_IDLEST,
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_ETHERNET_1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &dm816x_emac_hwmod_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_hs__emac1 = {
+ .master = &dm816x_l4_hs_hwmod,
+ .slave = &dm816x_emac1_hwmod,
+ .clk = "sysclk5_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig dm816x_mmc_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x110,
+ .syss_offs = 0x114,
+ .sysc_flags = SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class dm816x_mmc_class = {
+ .name = "mmc",
+ .sysc = &dm816x_mmc_sysc,
+};
+
+static struct omap_hwmod_opt_clk dm816x_mmc1_opt_clks[] = {
+ { .role = "dbck", .clk = "sysclk18_ck", },
+};
+
+static struct omap_hsmmc_dev_attr mmc1_dev_attr = {
+ .flags = OMAP_HSMMC_SUPPORTS_DUAL_VOLT,
+};
+
+static struct omap_hwmod dm816x_mmc1_hwmod = {
+ .name = "mmc1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .opt_clks = dm816x_mmc1_opt_clks,
+ .opt_clks_cnt = ARRAY_SIZE(dm816x_mmc1_opt_clks),
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_SDIO_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .dev_attr = &mmc1_dev_attr,
+ .class = &dm816x_mmc_class,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__mmc1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_mmc1_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+ .flags = OMAP_FIREWALL_L4
+};
+
+static struct omap_hwmod_class_sysconfig dm816x_mcspi_sysc = {
+ .rev_offs = 0x0,
+ .sysc_offs = 0x110,
+ .syss_offs = 0x114,
+ .sysc_flags = SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_ENAWAKEUP | SYSC_HAS_SOFTRESET |
+ SYSC_HAS_AUTOIDLE | SYSS_HAS_RESET_STATUS,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class dm816x_mcspi_class = {
+ .name = "mcspi",
+ .sysc = &dm816x_mcspi_sysc,
+ .rev = OMAP3_MCSPI_REV,
+};
+
+static struct omap2_mcspi_dev_attr dm816x_mcspi1_dev_attr = {
+ .num_chipselect = 4,
+};
+
+static struct omap_hwmod dm816x_mcspi1_hwmod = {
+ .name = "mcspi1",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk10_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_SPI_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+ .class = &dm816x_mcspi_class,
+ .dev_attr = &dm816x_mcspi1_dev_attr,
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__mcspi1 = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_mcspi1_hwmod,
+ .clk = "sysclk6_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class_sysconfig dm816x_mailbox_sysc = {
+ .rev_offs = 0x000,
+ .sysc_offs = 0x010,
+ .syss_offs = 0x014,
+ .sysc_flags = SYSC_HAS_CLOCKACTIVITY | SYSC_HAS_SIDLEMODE |
+ SYSC_HAS_SOFTRESET | SYSC_HAS_AUTOIDLE,
+ .idlemodes = SIDLE_FORCE | SIDLE_NO | SIDLE_SMART,
+ .sysc_fields = &omap_hwmod_sysc_type1,
+};
+
+static struct omap_hwmod_class dm816x_mailbox_hwmod_class = {
+ .name = "mailbox",
+ .sysc = &dm816x_mailbox_sysc,
+};
+
+static struct omap_hwmod dm816x_mailbox_hwmod = {
+ .name = "mailbox",
+ .clkdm_name = "alwon_l3s_clkdm",
+ .class = &dm816x_mailbox_hwmod_class,
+ .main_clk = "sysclk6_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_MAILBOX_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+static struct omap_hwmod_ocp_if dm816x_l4_ls__mailbox = {
+ .master = &dm816x_l4_ls_hwmod,
+ .slave = &dm816x_mailbox_hwmod,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_class dm816x_tpcc_hwmod_class = {
+ .name = "tpcc",
+};
+
+struct omap_hwmod dm816x_tpcc_hwmod = {
+ .name = "tpcc",
+ .class = &dm816x_tpcc_hwmod_class,
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk4_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TPCC_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tpcc = {
+ .master = &dm816x_alwon_l3_fast_hwmod,
+ .slave = &dm816x_tpcc_hwmod,
+ .clk = "sysclk4_ck",
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space dm816x_tptc0_addr_space[] = {
+ {
+ .pa_start = 0x49800000,
+ .pa_end = 0x49800000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { },
+};
+
+static struct omap_hwmod_class dm816x_tptc0_hwmod_class = {
+ .name = "tptc0",
+};
+
+struct omap_hwmod dm816x_tptc0_hwmod = {
+ .name = "tptc0",
+ .class = &dm816x_tptc0_hwmod_class,
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk4_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TPTC0_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc0 = {
+ .master = &dm816x_alwon_l3_fast_hwmod,
+ .slave = &dm816x_tptc0_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc0_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if dm816x_tptc0__alwon_l3_fast = {
+ .master = &dm816x_tptc0_hwmod,
+ .slave = &dm816x_alwon_l3_fast_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc0_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space dm816x_tptc1_addr_space[] = {
+ {
+ .pa_start = 0x49900000,
+ .pa_end = 0x49900000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { },
+};
+
+static struct omap_hwmod_class dm816x_tptc1_hwmod_class = {
+ .name = "tptc1",
+};
+
+struct omap_hwmod dm816x_tptc1_hwmod = {
+ .name = "tptc1",
+ .class = &dm816x_tptc1_hwmod_class,
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk4_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TPTC1_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc1 = {
+ .master = &dm816x_alwon_l3_fast_hwmod,
+ .slave = &dm816x_tptc1_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc1_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if dm816x_tptc1__alwon_l3_fast = {
+ .master = &dm816x_tptc1_hwmod,
+ .slave = &dm816x_alwon_l3_fast_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc1_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space dm816x_tptc2_addr_space[] = {
+ {
+ .pa_start = 0x49a00000,
+ .pa_end = 0x49a00000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { },
+};
+
+static struct omap_hwmod_class dm816x_tptc2_hwmod_class = {
+ .name = "tptc2",
+};
+
+struct omap_hwmod dm816x_tptc2_hwmod = {
+ .name = "tptc2",
+ .class = &dm816x_tptc2_hwmod_class,
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk4_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TPTC2_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc2 = {
+ .master = &dm816x_alwon_l3_fast_hwmod,
+ .slave = &dm816x_tptc2_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc2_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if dm816x_tptc2__alwon_l3_fast = {
+ .master = &dm816x_tptc2_hwmod,
+ .slave = &dm816x_alwon_l3_fast_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc2_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_addr_space dm816x_tptc3_addr_space[] = {
+ {
+ .pa_start = 0x49b00000,
+ .pa_end = 0x49b00000 + SZ_8K - 1,
+ .flags = ADDR_TYPE_RT,
+ },
+ { },
+};
+
+static struct omap_hwmod_class dm816x_tptc3_hwmod_class = {
+ .name = "tptc3",
+};
+
+struct omap_hwmod dm816x_tptc3_hwmod = {
+ .name = "tptc3",
+ .class = &dm816x_tptc3_hwmod_class,
+ .clkdm_name = "alwon_l3s_clkdm",
+ .main_clk = "sysclk4_ck",
+ .prcm = {
+ .omap4 = {
+ .clkctrl_offs = DM816X_CM_ALWON_TPTC3_CLKCTRL,
+ .modulemode = MODULEMODE_SWCTRL,
+ },
+ },
+};
+
+struct omap_hwmod_ocp_if dm816x_alwon_l3_fast__tptc3 = {
+ .master = &dm816x_alwon_l3_fast_hwmod,
+ .slave = &dm816x_tptc3_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc3_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+struct omap_hwmod_ocp_if dm816x_tptc3__alwon_l3_fast = {
+ .master = &dm816x_tptc3_hwmod,
+ .slave = &dm816x_alwon_l3_fast_hwmod,
+ .clk = "sysclk4_ck",
+ .addr = dm816x_tptc3_addr_space,
+ .user = OCP_USER_MPU,
+};
+
+static struct omap_hwmod_ocp_if *dm816x_hwmod_ocp_ifs[] __initdata = {
+ &dm816x_mpu__alwon_l3_slow,
+ &dm816x_mpu__alwon_l3_med,
+ &dm816x_alwon_l3_slow__l4_ls,
+ &dm816x_alwon_l3_slow__l4_hs,
+ &dm816x_l4_ls__uart1,
+ &dm816x_l4_ls__uart2,
+ &dm816x_l4_ls__uart3,
+ &dm816x_l4_ls__wd_timer1,
+ &dm816x_l4_ls__i2c1,
+ &dm816x_l4_ls__i2c2,
+ &dm81xx_l4_ls__gpio1,
+ &dm81xx_l4_ls__gpio2,
+ &dm81xx_l4_ls__elm,
+ &dm816x_l4_ls__mmc1,
+ &dm816x_l4_ls__timer1,
+ &dm816x_l4_ls__timer2,
+ &dm816x_l4_ls__timer3,
+ &dm816x_l4_ls__timer4,
+ &dm816x_l4_ls__timer5,
+ &dm816x_l4_ls__timer6,
+ &dm816x_l4_ls__timer7,
+ &dm816x_l4_ls__mcspi1,
+ &dm816x_l4_ls__mailbox,
+ &dm816x_l4_hs__emac0,
+ &dm816x_emac0__mdio,
+ &dm816x_l4_hs__emac1,
+ &dm816x_alwon_l3_fast__tpcc,
+ &dm816x_alwon_l3_fast__tptc0,
+ &dm816x_alwon_l3_fast__tptc1,
+ &dm816x_alwon_l3_fast__tptc2,
+ &dm816x_alwon_l3_fast__tptc3,
+ &dm816x_tptc0__alwon_l3_fast,
+ &dm816x_tptc1__alwon_l3_fast,
+ &dm816x_tptc2__alwon_l3_fast,
+ &dm816x_tptc3__alwon_l3_fast,
+ &dm81xx_alwon_l3_slow__gpmc,
+ &dm81xx_default_l3_slow__usbss,
+ NULL,
+};
+
+int __init ti81xx_hwmod_init(void)
+{
+ omap_hwmod_init();
+ return omap_hwmod_register_links(dm816x_hwmod_ocp_ifs);
+}
diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c
index 1a19fa096bab..8e903564ede2 100644
--- a/arch/arm/mach-omap2/omap_phy_internal.c
+++ b/arch/arm/mach-omap2/omap_phy_internal.c
@@ -152,38 +152,3 @@ void am35x_set_mode(u8 musb_mode)
omap_ctrl_writel(devconf2, AM35XX_CONTROL_DEVCONF2);
}
-
-void ti81xx_musb_phy_power(u8 on)
-{
- void __iomem *scm_base = NULL;
- u32 usbphycfg;
-
- scm_base = ioremap(TI81XX_SCM_BASE, SZ_2K);
- if (!scm_base) {
- pr_err("system control module ioremap failed\n");
- return;
- }
-
- usbphycfg = readl_relaxed(scm_base + USBCTRL0);
-
- if (on) {
- if (cpu_is_ti816x()) {
- usbphycfg |= TI816X_USBPHY0_NORMAL_MODE;
- usbphycfg &= ~TI816X_USBPHY_REFCLK_OSC;
- } else if (cpu_is_ti814x()) {
- usbphycfg &= ~(USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN
- | USBPHY_DPINPUT | USBPHY_DMINPUT);
- usbphycfg |= (USBPHY_OTGVDET_EN | USBPHY_OTGSESSEND_EN
- | USBPHY_DPOPBUFCTL | USBPHY_DMOPBUFCTL);
- }
- } else {
- if (cpu_is_ti816x())
- usbphycfg &= ~TI816X_USBPHY0_NORMAL_MODE;
- else if (cpu_is_ti814x())
- usbphycfg |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN;
-
- }
- writel_relaxed(usbphycfg, scm_base + USBCTRL0);
-
- iounmap(scm_base);
-}
diff --git a/arch/arm/mach-omap2/pdata-quirks.c b/arch/arm/mach-omap2/pdata-quirks.c
index 3d7eee1d3cfa..190fa43e7479 100644
--- a/arch/arm/mach-omap2/pdata-quirks.c
+++ b/arch/arm/mach-omap2/pdata-quirks.c
@@ -19,7 +19,6 @@
#include <linux/platform_data/pinctrl-single.h>
#include <linux/platform_data/iommu-omap.h>
-#include "am35xx.h"
#include "common.h"
#include "common-board-devices.h"
#include "dss-common.h"
diff --git a/arch/arm/mach-omap2/pmu.c b/arch/arm/mach-omap2/pmu.c
index 33c8846b4193..a69e9a33cb6d 100644
--- a/arch/arm/mach-omap2/pmu.c
+++ b/arch/arm/mach-omap2/pmu.c
@@ -13,7 +13,7 @@
*/
#include <linux/of.h>
-#include <asm/pmu.h>
+#include <asm/system_info.h>
#include "soc.h"
#include "omap_hwmod.h"
@@ -37,7 +37,8 @@ static int __init omap2_init_pmu(unsigned oh_num, char *oh_names[])
{
int i;
struct omap_hwmod *oh[3];
- char *dev_name = "arm-pmu";
+ char *dev_name = cpu_architecture() == CPU_ARCH_ARMv6 ?
+ "armv6-pmu" : "armv7-pmu";
if ((!oh_num) || (oh_num > 3))
return -EINVAL;
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c
index 7fb033eca0a5..78af6d8cf2e2 100644
--- a/arch/arm/mach-omap2/powerdomain.c
+++ b/arch/arm/mach-omap2/powerdomain.c
@@ -115,7 +115,6 @@ static int _pwrdm_register(struct powerdomain *pwrdm)
}
pwrdm->voltdm.ptr = voltdm;
INIT_LIST_HEAD(&pwrdm->voltdm_node);
- voltdm_add_pwrdm(voltdm, pwrdm);
skip_voltdm:
spin_lock_init(&pwrdm->_lock);
@@ -484,87 +483,6 @@ pac_exit:
}
/**
- * pwrdm_del_clkdm - remove a clockdomain from a powerdomain
- * @pwrdm: struct powerdomain * to add the clockdomain to
- * @clkdm: struct clockdomain * to associate with a powerdomain
- *
- * Dissociate the clockdomain @clkdm from the powerdomain
- * @pwrdm. Returns -EINVAL if presented with invalid pointers; -ENOENT
- * if @clkdm was not associated with the powerdomain, or 0 upon
- * success.
- */
-int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm)
-{
- int ret = -EINVAL;
- int i;
-
- if (!pwrdm || !clkdm)
- return -EINVAL;
-
- pr_debug("powerdomain: %s: dissociating clockdomain %s\n",
- pwrdm->name, clkdm->name);
-
- for (i = 0; i < PWRDM_MAX_CLKDMS; i++)
- if (pwrdm->pwrdm_clkdms[i] == clkdm)
- break;
-
- if (i == PWRDM_MAX_CLKDMS) {
- pr_debug("powerdomain: %s: clkdm %s not associated?!\n",
- pwrdm->name, clkdm->name);
- ret = -ENOENT;
- goto pdc_exit;
- }
-
- pwrdm->pwrdm_clkdms[i] = NULL;
-
- ret = 0;
-
-pdc_exit:
- return ret;
-}
-
-/**
- * pwrdm_for_each_clkdm - call function on each clkdm in a pwrdm
- * @pwrdm: struct powerdomain * to iterate over
- * @fn: callback function *
- *
- * Call the supplied function @fn for each clockdomain in the powerdomain
- * @pwrdm. The callback function can return anything but 0 to bail
- * out early from the iterator. Returns -EINVAL if presented with
- * invalid pointers; or passes along the last return value of the
- * callback function, which should be 0 for success or anything else
- * to indicate failure.
- */
-int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
- int (*fn)(struct powerdomain *pwrdm,
- struct clockdomain *clkdm))
-{
- int ret = 0;
- int i;
-
- if (!fn)
- return -EINVAL;
-
- for (i = 0; i < PWRDM_MAX_CLKDMS && !ret; i++)
- if (pwrdm->pwrdm_clkdms[i])
- ret = (*fn)(pwrdm, pwrdm->pwrdm_clkdms[i]);
-
- return ret;
-}
-
-/**
- * pwrdm_get_voltdm - return a ptr to the voltdm that this pwrdm resides in
- * @pwrdm: struct powerdomain *
- *
- * Return a pointer to the struct voltageomain that the specified powerdomain
- * @pwrdm exists in.
- */
-struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm)
-{
- return pwrdm->voltdm.ptr;
-}
-
-/**
* pwrdm_get_mem_bank_count - get number of memory banks in this powerdomain
* @pwrdm: struct powerdomain *
*
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h
index 11bd4dd7d8d6..28a796ce07d7 100644
--- a/arch/arm/mach-omap2/powerdomain.h
+++ b/arch/arm/mach-omap2/powerdomain.h
@@ -212,11 +212,6 @@ int pwrdm_for_each_nolock(int (*fn)(struct powerdomain *pwrdm, void *user),
void *user);
int pwrdm_add_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
-int pwrdm_del_clkdm(struct powerdomain *pwrdm, struct clockdomain *clkdm);
-int pwrdm_for_each_clkdm(struct powerdomain *pwrdm,
- int (*fn)(struct powerdomain *pwrdm,
- struct clockdomain *clkdm));
-struct voltagedomain *pwrdm_get_voltdm(struct powerdomain *pwrdm);
int pwrdm_get_mem_bank_count(struct powerdomain *pwrdm);
diff --git a/arch/arm/mach-omap2/powerdomains3xxx_data.c b/arch/arm/mach-omap2/powerdomains3xxx_data.c
index 328c1037cb60..70bc7066a4c2 100644
--- a/arch/arm/mach-omap2/powerdomains3xxx_data.c
+++ b/arch/arm/mach-omap2/powerdomains3xxx_data.c
@@ -464,7 +464,7 @@ void __init omap3xxx_powerdomains_init(void)
{
unsigned int rev;
- if (!cpu_is_omap34xx())
+ if (!cpu_is_omap34xx() && !cpu_is_ti81xx())
return;
pwrdm_register_platform_funcs(&omap3_pwrdm_operations);
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h
index a8e4b582c527..6163d66102a3 100644
--- a/arch/arm/mach-omap2/prcm-common.h
+++ b/arch/arm/mach-omap2/prcm-common.h
@@ -498,6 +498,7 @@ struct omap_prcm_irq_setup {
u8 nr_irqs;
const struct omap_prcm_irq *irqs;
int irq;
+ unsigned int (*xlate_irq)(unsigned int);
void (*read_pending_irqs)(unsigned long *events);
void (*ocp_barrier)(void);
void (*save_and_clear_irqen)(u32 *saved_mask);
diff --git a/arch/arm/mach-omap2/prm3xxx.h b/arch/arm/mach-omap2/prm3xxx.h
index cfde3f4a03cc..ed8a3d8b739a 100644
--- a/arch/arm/mach-omap2/prm3xxx.h
+++ b/arch/arm/mach-omap2/prm3xxx.h
@@ -145,7 +145,6 @@ extern void omap3_prm_vcvp_write(u32 val, u8 offset);
extern u32 omap3_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
extern int __init omap3xxx_prm_init(void);
-extern u32 omap3xxx_prm_get_reset_sources(void);
int omap3xxx_prm_clear_mod_irqs(s16 module, u8 regs, u32 ignore_bits);
void omap3xxx_prm_iva_idle(void);
void omap3_prm_reset_modem(void);
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c
index cc170fb81ff7..408c64efb807 100644
--- a/arch/arm/mach-omap2/prm44xx.c
+++ b/arch/arm/mach-omap2/prm44xx.c
@@ -49,6 +49,7 @@ static struct omap_prcm_irq_setup omap4_prcm_irq_setup = {
.irqs = omap4_prcm_irqs,
.nr_irqs = ARRAY_SIZE(omap4_prcm_irqs),
.irq = 11 + OMAP44XX_IRQ_GIC_START,
+ .xlate_irq = omap4_xlate_irq,
.read_pending_irqs = &omap44xx_prm_read_pending_irqs,
.ocp_barrier = &omap44xx_prm_ocp_barrier,
.save_and_clear_irqen = &omap44xx_prm_save_and_clear_irqen,
@@ -751,8 +752,10 @@ static int omap44xx_prm_late_init(void)
}
/* Once OMAP4 DT is filled as well */
- if (irq_num >= 0)
+ if (irq_num >= 0) {
omap4_prcm_irq_setup.irq = irq_num;
+ omap4_prcm_irq_setup.xlate_irq = NULL;
+ }
}
omap44xx_prm_enable_io_wakeup();
diff --git a/arch/arm/mach-omap2/prm44xx_54xx.h b/arch/arm/mach-omap2/prm44xx_54xx.h
index f7512515fde5..714329565b90 100644
--- a/arch/arm/mach-omap2/prm44xx_54xx.h
+++ b/arch/arm/mach-omap2/prm44xx_54xx.h
@@ -39,7 +39,6 @@ extern void omap4_prm_vcvp_write(u32 val, u8 offset);
extern u32 omap4_prm_vcvp_rmw(u32 mask, u32 bits, u8 offset);
extern int __init omap44xx_prm_init(void);
-extern u32 omap44xx_prm_get_reset_sources(void);
#endif
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c
index 779940cb6e56..264b5e29404d 100644
--- a/arch/arm/mach-omap2/prm_common.c
+++ b/arch/arm/mach-omap2/prm_common.c
@@ -187,6 +187,7 @@ int omap_prcm_event_to_irq(const char *name)
*/
void omap_prcm_irq_cleanup(void)
{
+ unsigned int irq;
int i;
if (!prcm_irq_setup) {
@@ -211,7 +212,11 @@ void omap_prcm_irq_cleanup(void)
kfree(prcm_irq_setup->priority_mask);
prcm_irq_setup->priority_mask = NULL;
- irq_set_chained_handler(prcm_irq_setup->irq, NULL);
+ if (prcm_irq_setup->xlate_irq)
+ irq = prcm_irq_setup->xlate_irq(prcm_irq_setup->irq);
+ else
+ irq = prcm_irq_setup->irq;
+ irq_set_chained_handler(irq, NULL);
if (prcm_irq_setup->base_irq > 0)
irq_free_descs(prcm_irq_setup->base_irq,
@@ -259,6 +264,7 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
int offset, i;
struct irq_chip_generic *gc;
struct irq_chip_type *ct;
+ unsigned int irq;
if (!irq_setup)
return -EINVAL;
@@ -298,7 +304,11 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup)
1 << (offset & 0x1f);
}
- irq_set_chained_handler(irq_setup->irq, omap_prcm_irq_handler);
+ if (irq_setup->xlate_irq)
+ irq = irq_setup->xlate_irq(irq_setup->irq);
+ else
+ irq = irq_setup->irq;
+ irq_set_chained_handler(irq, omap_prcm_irq_handler);
irq_setup->base_irq = irq_alloc_descs(-1, 0, irq_setup->nr_regs * 32,
0);
@@ -571,6 +581,10 @@ static const struct of_device_id omap_prcm_dt_match_table[] = {
{ .compatible = "ti,am3-scrm" },
{ .compatible = "ti,am4-prcm" },
{ .compatible = "ti,am4-scrm" },
+ { .compatible = "ti,dm814-prcm" },
+ { .compatible = "ti,dm814-scrm" },
+ { .compatible = "ti,dm816-prcm" },
+ { .compatible = "ti,dm816-scrm" },
{ .compatible = "ti,omap2-prcm" },
{ .compatible = "ti,omap2-scrm" },
{ .compatible = "ti,omap3-prm" },
diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h
index c1a3b4416311..f97654d11ea5 100644
--- a/arch/arm/mach-omap2/soc.h
+++ b/arch/arm/mach-omap2/soc.h
@@ -423,13 +423,13 @@ IS_OMAP_TYPE(3430, 0x3430)
#define OMAP3630_REV_ES1_1 (OMAP363X_CLASS | (0x1 << 8))
#define OMAP3630_REV_ES1_2 (OMAP363X_CLASS | (0x2 << 8))
-#define TI816X_CLASS 0x81600034
+#define TI816X_CLASS 0x81600081
#define TI8168_REV_ES1_0 TI816X_CLASS
#define TI8168_REV_ES1_1 (TI816X_CLASS | (0x1 << 8))
#define TI8168_REV_ES2_0 (TI816X_CLASS | (0x2 << 8))
#define TI8168_REV_ES2_1 (TI816X_CLASS | (0x3 << 8))
-#define TI814X_CLASS 0x81400034
+#define TI814X_CLASS 0x81400081
#define TI8148_REV_ES1_0 TI814X_CLASS
#define TI8148_REV_ES2_0 (TI814X_CLASS | (0x1 << 8))
#define TI8148_REV_ES2_1 (TI814X_CLASS | (0x2 << 8))
diff --git a/arch/arm/mach-omap2/ti81xx-restart.c b/arch/arm/mach-omap2/ti81xx-restart.c
new file mode 100644
index 000000000000..6c3ce7c46ddd
--- /dev/null
+++ b/arch/arm/mach-omap2/ti81xx-restart.c
@@ -0,0 +1,34 @@
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/reboot.h>
+
+#include "iomap.h"
+#include "common.h"
+#include "control.h"
+#include "prm3xxx.h"
+
+#define TI81XX_PRM_DEVICE_RSTCTRL 0x00a0
+#define TI81XX_GLOBAL_RST_COLD BIT(1)
+
+/**
+ * ti81xx_restart - trigger a software restart of the SoC
+ * @mode: the "reboot mode", see arch/arm/kernel/{setup,process}.c
+ * @cmd: passed from the userspace program rebooting the system (if provided)
+ *
+ * Resets the SoC. For @cmd, see the 'reboot' syscall in
+ * kernel/sys.c. No return value.
+ *
+ * NOTE: Warm reset does not seem to work, may require resetting
+ * clocks to bypass mode.
+ */
+void ti81xx_restart(enum reboot_mode mode, const char *cmd)
+{
+ omap2_prm_set_mod_reg_bits(TI81XX_GLOBAL_RST_COLD, 0,
+ TI81XX_PRM_DEVICE_RSTCTRL);
+ while (1);
+}
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c
index 4f61148ec168..cef67af9e9b8 100644
--- a/arch/arm/mach-omap2/timer.c
+++ b/arch/arm/mach-omap2/timer.c
@@ -54,6 +54,7 @@
#include "soc.h"
#include "common.h"
+#include "control.h"
#include "powerdomain.h"
#include "omap-secure.h"
@@ -146,6 +147,8 @@ static const struct of_device_id omap_timer_match[] __initconst = {
{ .compatible = "ti,omap3430-timer", },
{ .compatible = "ti,omap4430-timer", },
{ .compatible = "ti,omap5430-timer", },
+ { .compatible = "ti,dm814-timer", },
+ { .compatible = "ti,dm816-timer", },
{ .compatible = "ti,am335x-timer", },
{ .compatible = "ti,am335x-timer-1ms", },
{ }
@@ -496,7 +499,8 @@ static void __init realtime_counter_init(void)
void __iomem *base;
static struct clk *sys_clk;
unsigned long rate;
- unsigned int reg, num, den;
+ unsigned int reg;
+ unsigned long long num, den;
base = ioremap(REALTIME_COUNTER_BASE, SZ_32);
if (!base) {
@@ -511,13 +515,42 @@ static void __init realtime_counter_init(void)
}
rate = clk_get_rate(sys_clk);
+
+ if (soc_is_dra7xx()) {
+ /*
+ * Errata i856 says the 32.768KHz crystal does not start at
+ * power on, so the CPU falls back to an emulated 32KHz clock
+ * based on sysclk / 610 instead. This causes the master counter
+ * frequency to not be 6.144MHz but at sysclk / 610 * 375 / 2
+ * (OR sysclk * 75 / 244)
+ *
+ * This affects at least the DRA7/AM572x 1.0, 1.1 revisions.
+ * Of course any board built without a populated 32.768KHz
+ * crystal would also need this fix even if the CPU is fixed
+ * later.
+ *
+ * Either case can be detected by using the two speedselect bits
+ * If they are not 0, then the 32.768KHz clock driving the
+ * coarse counter that corrects the fine counter every time it
+ * ticks is actually rate/610 rather than 32.768KHz and we
+ * should compensate to avoid the 570ppm (at 20MHz, much worse
+ * at other rates) too fast system time.
+ */
+ reg = omap_ctrl_readl(DRA7_CTRL_CORE_BOOTSTRAP);
+ if (reg & DRA7_SPEEDSELECT_MASK) {
+ num = 75;
+ den = 244;
+ goto sysclk1_based;
+ }
+ }
+
/* Numerator/denumerator values refer TRM Realtime Counter section */
switch (rate) {
- case 1200000:
+ case 12000000:
num = 64;
den = 125;
break;
- case 1300000:
+ case 13000000:
num = 768;
den = 1625;
break;
@@ -529,11 +562,11 @@ static void __init realtime_counter_init(void)
num = 192;
den = 625;
break;
- case 2600000:
+ case 26000000:
num = 384;
den = 1625;
break;
- case 2700000:
+ case 27000000:
num = 256;
den = 1125;
break;
@@ -545,6 +578,7 @@ static void __init realtime_counter_init(void)
break;
}
+sysclk1_based:
/* Program numerator and denumerator registers */
reg = readl_relaxed(base + INCREMENTER_NUMERATOR_OFFSET) &
NUMERATOR_DENUMERATOR_MASK;
@@ -556,7 +590,7 @@ static void __init realtime_counter_init(void)
reg |= den;
writel_relaxed(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET);
- arch_timer_freq = (rate / den) * num;
+ arch_timer_freq = DIV_ROUND_UP_ULL(rate * num, den);
set_cntfreq();
iounmap(base);
diff --git a/arch/arm/mach-omap2/twl-common.c b/arch/arm/mach-omap2/twl-common.c
index 4457e731f7a4..292eca0e78ed 100644
--- a/arch/arm/mach-omap2/twl-common.c
+++ b/arch/arm/mach-omap2/twl-common.c
@@ -66,19 +66,24 @@ void __init omap_pmic_init(int bus, u32 clkrate,
omap_register_i2c_bus(bus, clkrate, &pmic_i2c_board_info, 1);
}
+#ifdef CONFIG_ARCH_OMAP4
void __init omap4_pmic_init(const char *pmic_type,
struct twl4030_platform_data *pmic_data,
struct i2c_board_info *devices, int nr_devices)
{
/* PMIC part*/
+ unsigned int irq;
+
omap_mux_init_signal("sys_nirq1", OMAP_PIN_INPUT_PULLUP | OMAP_PIN_OFF_WAKEUPENABLE);
omap_mux_init_signal("fref_clk0_out.sys_drm_msecure", OMAP_PIN_OUTPUT);
- omap_pmic_init(1, 400, pmic_type, 7 + OMAP44XX_IRQ_GIC_START, pmic_data);
+ irq = omap4_xlate_irq(7 + OMAP44XX_IRQ_GIC_START);
+ omap_pmic_init(1, 400, pmic_type, irq, pmic_data);
/* Register additional devices on i2c1 bus if needed */
if (devices)
i2c_register_board_info(1, devices, nr_devices);
}
+#endif
void __init omap_pmic_late_init(void)
{
diff --git a/arch/arm/mach-omap2/usb-musb.c b/arch/arm/mach-omap2/usb-musb.c
index bc897231bd10..e4562b2b973b 100644
--- a/arch/arm/mach-omap2/usb-musb.c
+++ b/arch/arm/mach-omap2/usb-musb.c
@@ -82,16 +82,8 @@ void __init usb_musb_init(struct omap_musb_board_data *musb_board_data)
musb_plat.mode = board_data->mode;
musb_plat.extvbus = board_data->extvbus;
- if (soc_is_am35xx()) {
- oh_name = "am35x_otg_hs";
- name = "musb-am35x";
- } else if (cpu_is_ti81xx()) {
- oh_name = "usb_otg_hs";
- name = "musb-ti81xx";
- } else {
- oh_name = "usb_otg_hs";
- name = "musb-omap2430";
- }
+ oh_name = "usb_otg_hs";
+ name = "musb-omap2430";
oh = omap_hwmod_lookup(oh_name);
if (WARN(!oh, "%s: could not find omap_hwmod for %s\n",
diff --git a/arch/arm/mach-omap2/usb.h b/arch/arm/mach-omap2/usb.h
index 4ba2ae759895..3395365ef1db 100644
--- a/arch/arm/mach-omap2/usb.h
+++ b/arch/arm/mach-omap2/usb.h
@@ -68,5 +68,3 @@ extern void am35x_musb_reset(void);
extern void am35x_musb_phy_power(u8 on);
extern void am35x_musb_clear_irq(void);
extern void am35x_set_mode(u8 musb_mode);
-extern void ti81xx_musb_phy_power(u8 on);
-
diff --git a/arch/arm/mach-omap2/voltage.c b/arch/arm/mach-omap2/voltage.c
index 3783b8625f0f..cba8cada8c81 100644
--- a/arch/arm/mach-omap2/voltage.c
+++ b/arch/arm/mach-omap2/voltage.c
@@ -224,37 +224,6 @@ int omap_voltage_register_pmic(struct voltagedomain *voltdm,
}
/**
- * omap_change_voltscale_method() - API to change the voltage scaling method.
- * @voltdm: pointer to the VDD whose voltage scaling method
- * has to be changed.
- * @voltscale_method: the method to be used for voltage scaling.
- *
- * This API can be used by the board files to change the method of voltage
- * scaling between vpforceupdate and vcbypass. The parameter values are
- * defined in voltage.h
- */
-void omap_change_voltscale_method(struct voltagedomain *voltdm,
- int voltscale_method)
-{
- if (!voltdm || IS_ERR(voltdm)) {
- pr_warn("%s: VDD specified does not exist!\n", __func__);
- return;
- }
-
- switch (voltscale_method) {
- case VOLTSCALE_VPFORCEUPDATE:
- voltdm->scale = omap_vp_forceupdate_scale;
- return;
- case VOLTSCALE_VCBYPASS:
- voltdm->scale = omap_vc_bypass_scale;
- return;
- default:
- pr_warn("%s: Trying to change the method of voltage scaling to an unsupported one!\n",
- __func__);
- }
-}
-
-/**
* omap_voltage_late_init() - Init the various voltage parameters
*
* This API is to be called in the later stages of the
@@ -316,90 +285,11 @@ static struct voltagedomain *_voltdm_lookup(const char *name)
return voltdm;
}
-/**
- * voltdm_add_pwrdm - add a powerdomain to a voltagedomain
- * @voltdm: struct voltagedomain * to add the powerdomain to
- * @pwrdm: struct powerdomain * to associate with a voltagedomain
- *
- * Associate the powerdomain @pwrdm with a voltagedomain @voltdm. This
- * enables the use of voltdm_for_each_pwrdm(). Returns -EINVAL if
- * presented with invalid pointers; -ENOMEM if memory could not be allocated;
- * or 0 upon success.
- */
-int voltdm_add_pwrdm(struct voltagedomain *voltdm, struct powerdomain *pwrdm)
-{
- if (!voltdm || !pwrdm)
- return -EINVAL;
-
- pr_debug("voltagedomain: %s: associating powerdomain %s\n",
- voltdm->name, pwrdm->name);
-
- list_add(&pwrdm->voltdm_node, &voltdm->pwrdm_list);
-
- return 0;
-}
-
-/**
- * voltdm_for_each_pwrdm - call function for each pwrdm in a voltdm
- * @voltdm: struct voltagedomain * to iterate over
- * @fn: callback function *
- *
- * Call the supplied function @fn for each powerdomain in the
- * voltagedomain @voltdm. Returns -EINVAL if presented with invalid
- * pointers; or passes along the last return value of the callback
- * function, which should be 0 for success or anything else to
- * indicate failure.
- */
-int voltdm_for_each_pwrdm(struct voltagedomain *voltdm,
- int (*fn)(struct voltagedomain *voltdm,
- struct powerdomain *pwrdm))
-{
- struct powerdomain *pwrdm;
- int ret = 0;
-
- if (!fn)
- return -EINVAL;
-
- list_for_each_entry(pwrdm, &voltdm->pwrdm_list, voltdm_node)
- ret = (*fn)(voltdm, pwrdm);
-
- return ret;
-}
-
-/**
- * voltdm_for_each - call function on each registered voltagedomain
- * @fn: callback function *
- *
- * Call the supplied function @fn for each registered voltagedomain.
- * The callback function @fn can return anything but 0 to bail out
- * early from the iterator. Returns the last return value of the
- * callback function, which should be 0 for success or anything else
- * to indicate failure; or -EINVAL if the function pointer is null.
- */
-int voltdm_for_each(int (*fn)(struct voltagedomain *voltdm, void *user),
- void *user)
-{
- struct voltagedomain *temp_voltdm;
- int ret = 0;
-
- if (!fn)
- return -EINVAL;
-
- list_for_each_entry(temp_voltdm, &voltdm_list, node) {
- ret = (*fn)(temp_voltdm, user);
- if (ret)
- break;
- }
-
- return ret;
-}
-
static int _voltdm_register(struct voltagedomain *voltdm)
{
if (!voltdm || !voltdm->name)
return -EINVAL;
- INIT_LIST_HEAD(&voltdm->pwrdm_list);
list_add(&voltdm->node, &voltdm_list);
pr_debug("voltagedomain: registered %s\n", voltdm->name);
diff --git a/arch/arm/mach-omap2/voltage.h b/arch/arm/mach-omap2/voltage.h
index f7f2879b31b0..e64550321510 100644
--- a/arch/arm/mach-omap2/voltage.h
+++ b/arch/arm/mach-omap2/voltage.h
@@ -23,10 +23,6 @@
struct powerdomain;
-/* XXX document */
-#define VOLTSCALE_VPFORCEUPDATE 1
-#define VOLTSCALE_VCBYPASS 2
-
/*
* OMAP3 GENERIC setup times. Revisit to see if these needs to be
* passed from board or PMIC file
@@ -55,7 +51,6 @@ struct omap_vfsm_instance {
* @name: Name of the voltage domain which can be used as a unique identifier.
* @scalable: Whether or not this voltage domain is scalable
* @node: list_head linking all voltage domains
- * @pwrdm_list: list_head linking all powerdomains in this voltagedomain
* @vc: pointer to VC channel associated with this voltagedomain
* @vp: pointer to VP associated with this voltagedomain
* @read: read a VC/VP register
@@ -71,7 +66,6 @@ struct voltagedomain {
char *name;
bool scalable;
struct list_head node;
- struct list_head pwrdm_list;
struct omap_vc_channel *vc;
const struct omap_vfsm_instance *vfsm;
struct omap_vp_instance *vp;
@@ -163,8 +157,6 @@ struct omap_volt_data *omap_voltage_get_voltdata(struct voltagedomain *voltdm,
unsigned long volt);
int omap_voltage_register_pmic(struct voltagedomain *voltdm,
struct omap_voltdm_pmic *pmic);
-void omap_change_voltscale_method(struct voltagedomain *voltdm,
- int voltscale_method);
int omap_voltage_late_init(void);
extern void omap2xxx_voltagedomains_init(void);
@@ -175,11 +167,6 @@ extern void omap54xx_voltagedomains_init(void);
struct voltagedomain *voltdm_lookup(const char *name);
void voltdm_init(struct voltagedomain **voltdm_list);
int voltdm_add_pwrdm(struct voltagedomain *voltdm, struct powerdomain *pwrdm);
-int voltdm_for_each(int (*fn)(struct voltagedomain *voltdm, void *user),
- void *user);
-int voltdm_for_each_pwrdm(struct voltagedomain *voltdm,
- int (*fn)(struct voltagedomain *voltdm,
- struct powerdomain *pwrdm));
int voltdm_scale(struct voltagedomain *voltdm, unsigned long target_volt);
void voltdm_reset(struct voltagedomain *voltdm);
unsigned long voltdm_get_voltage(struct voltagedomain *voltdm);
diff --git a/arch/arm/mach-prima2/Kconfig b/arch/arm/mach-prima2/Kconfig
index 042f693ef423..a219dc310d5d 100644
--- a/arch/arm/mach-prima2/Kconfig
+++ b/arch/arm/mach-prima2/Kconfig
@@ -11,7 +11,7 @@ menuconfig ARCH_SIRF
if ARCH_SIRF
-comment "CSR SiRF atlas6/primaII/Marco/Polo Specific Features"
+comment "CSR SiRF atlas6/primaII/Atlas7 Specific Features"
config ARCH_ATLAS6
bool "CSR SiRFSoC ATLAS6 ARM Cortex A9 Platform"
@@ -20,6 +20,17 @@ config ARCH_ATLAS6
help
Support for CSR SiRFSoC ARM Cortex A9 Platform
+config ARCH_ATLAS7
+ bool "CSR SiRFSoC ATLAS7 ARM Cortex A7 Platform"
+ default y
+ select ARM_GIC
+ select CPU_V7
+ select HAVE_ARM_SCU if SMP
+ select HAVE_SMP
+ select SMP_ON_UP if SMP
+ help
+ Support for CSR SiRFSoC ARM Cortex A7 Platform
+
config ARCH_PRIMA2
bool "CSR SiRFSoC PRIMA2 ARM Cortex A9 Platform"
default y
@@ -28,15 +39,6 @@ config ARCH_PRIMA2
help
Support for CSR SiRFSoC ARM Cortex A9 Platform
-config ARCH_MARCO
- bool "CSR SiRFSoC MARCO ARM Cortex A9 Platform"
- default y
- select ARM_GIC
- select HAVE_ARM_SCU if SMP
- select SMP_ON_UP if SMP
- help
- Support for CSR SiRFSoC ARM Cortex A9 Platform
-
config SIRF_IRQ
bool
diff --git a/arch/arm/mach-prima2/Makefile b/arch/arm/mach-prima2/Makefile
index 8846e7d87ea5..d7d02b043449 100644
--- a/arch/arm/mach-prima2/Makefile
+++ b/arch/arm/mach-prima2/Makefile
@@ -1,7 +1,6 @@
obj-y += rstc.o
obj-y += common.o
obj-y += rtciobrg.o
-obj-$(CONFIG_DEBUG_LL) += lluart.o
obj-$(CONFIG_SUSPEND) += pm.o sleep.o
obj-$(CONFIG_SMP) += platsmp.o headsmp.o
obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
diff --git a/arch/arm/mach-prima2/common.c b/arch/arm/mach-prima2/common.c
index a860ea27e8ae..0c819bb88418 100644
--- a/arch/arm/mach-prima2/common.c
+++ b/arch/arm/mach-prima2/common.c
@@ -20,12 +20,6 @@ static void __init sirfsoc_init_late(void)
sirfsoc_pm_init();
}
-static __init void sirfsoc_map_io(void)
-{
- sirfsoc_map_lluart();
- sirfsoc_map_scu();
-}
-
#ifdef CONFIG_ARCH_ATLAS6
static const char *atlas6_dt_match[] __initconst = {
"sirf,atlas6",
@@ -36,7 +30,6 @@ DT_MACHINE_START(ATLAS6_DT, "Generic ATLAS6 (Flattened Device Tree)")
/* Maintainer: Barry Song <baohua.song@csr.com> */
.l2c_aux_val = 0,
.l2c_aux_mask = ~0,
- .map_io = sirfsoc_map_io,
.init_late = sirfsoc_init_late,
.dt_compat = atlas6_dt_match,
MACHINE_END
@@ -52,26 +45,21 @@ DT_MACHINE_START(PRIMA2_DT, "Generic PRIMA2 (Flattened Device Tree)")
/* Maintainer: Barry Song <baohua.song@csr.com> */
.l2c_aux_val = 0,
.l2c_aux_mask = ~0,
- .map_io = sirfsoc_map_io,
.dma_zone_size = SZ_256M,
.init_late = sirfsoc_init_late,
.dt_compat = prima2_dt_match,
MACHINE_END
#endif
-#ifdef CONFIG_ARCH_MARCO
-static const char *marco_dt_match[] __initconst = {
- "sirf,marco",
+#ifdef CONFIG_ARCH_ATLAS7
+static const char *atlas7_dt_match[] __initdata = {
+ "sirf,atlas7",
NULL
};
-DT_MACHINE_START(MARCO_DT, "Generic MARCO (Flattened Device Tree)")
+DT_MACHINE_START(ATLAS7_DT, "Generic ATLAS7 (Flattened Device Tree)")
/* Maintainer: Barry Song <baohua.song@csr.com> */
- .l2c_aux_val = 0,
- .l2c_aux_mask = ~0,
.smp = smp_ops(sirfsoc_smp_ops),
- .map_io = sirfsoc_map_io,
- .init_late = sirfsoc_init_late,
- .dt_compat = marco_dt_match,
+ .dt_compat = atlas7_dt_match,
MACHINE_END
#endif
diff --git a/arch/arm/mach-prima2/common.h b/arch/arm/mach-prima2/common.h
index 07d3e5ed9264..3916a6665100 100644
--- a/arch/arm/mach-prima2/common.h
+++ b/arch/arm/mach-prima2/common.h
@@ -15,9 +15,6 @@
#include <asm/mach/time.h>
#include <asm/exception.h>
-#define SIRFSOC_VA_BASE _AC(0xFEC00000, UL)
-#define SIRFSOC_VA(x) (SIRFSOC_VA_BASE + ((x) & 0x00FFF000))
-
extern struct smp_operations sirfsoc_smp_ops;
extern void sirfsoc_secondary_startup(void);
extern void sirfsoc_cpu_die(unsigned int cpu);
@@ -25,18 +22,6 @@ extern void sirfsoc_cpu_die(unsigned int cpu);
extern void __init sirfsoc_of_irq_init(void);
extern asmlinkage void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs);
-#ifndef CONFIG_DEBUG_LL
-static inline void sirfsoc_map_lluart(void) {}
-#else
-extern void __init sirfsoc_map_lluart(void);
-#endif
-
-#ifndef CONFIG_SMP
-static inline void sirfsoc_map_scu(void) {}
-#else
-extern void sirfsoc_map_scu(void);
-#endif
-
#ifdef CONFIG_SUSPEND
extern int sirfsoc_pm_init(void);
#else
diff --git a/arch/arm/mach-prima2/lluart.c b/arch/arm/mach-prima2/lluart.c
deleted file mode 100644
index 99c0c927ca4a..000000000000
--- a/arch/arm/mach-prima2/lluart.c
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Static memory mapping for DEBUG_LL
- *
- * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
- *
- * Licensed under GPLv2 or later.
- */
-
-#include <linux/kernel.h>
-#include <asm/page.h>
-#include <asm/mach/map.h>
-#include "common.h"
-
-#if defined(CONFIG_DEBUG_SIRFPRIMA2_UART1)
-#define SIRFSOC_UART1_PA_BASE 0xb0060000
-#elif defined(CONFIG_DEBUG_SIRFMARCO_UART1)
-#define SIRFSOC_UART1_PA_BASE 0xcc060000
-#else
-#define SIRFSOC_UART1_PA_BASE 0
-#endif
-
-#define SIRFSOC_UART1_VA_BASE SIRFSOC_VA(0x060000)
-#define SIRFSOC_UART1_SIZE SZ_4K
-
-void __init sirfsoc_map_lluart(void)
-{
- struct map_desc sirfsoc_lluart_map = {
- .virtual = SIRFSOC_UART1_VA_BASE,
- .pfn = __phys_to_pfn(SIRFSOC_UART1_PA_BASE),
- .length = SIRFSOC_UART1_SIZE,
- .type = MT_DEVICE,
- };
-
- iotable_init(&sirfsoc_lluart_map, 1);
-}
diff --git a/arch/arm/mach-prima2/platsmp.c b/arch/arm/mach-prima2/platsmp.c
index 335c12e92262..fc2b03c81e5f 100644
--- a/arch/arm/mach-prima2/platsmp.c
+++ b/arch/arm/mach-prima2/platsmp.c
@@ -20,30 +20,10 @@
#include "common.h"
-static void __iomem *scu_base;
-static void __iomem *rsc_base;
+static void __iomem *clk_base;
static DEFINE_SPINLOCK(boot_lock);
-static struct map_desc scu_io_desc __initdata = {
- .length = SZ_4K,
- .type = MT_DEVICE,
-};
-
-void __init sirfsoc_map_scu(void)
-{
- unsigned long base;
-
- /* Get SCU base */
- asm("mrc p15, 4, %0, c15, c0, 0" : "=r" (base));
-
- scu_io_desc.virtual = SIRFSOC_VA(base);
- scu_io_desc.pfn = __phys_to_pfn(base);
- iotable_init(&scu_io_desc, 1);
-
- scu_base = (void __iomem *)SIRFSOC_VA(base);
-}
-
static void sirfsoc_secondary_init(unsigned int cpu)
{
/*
@@ -60,8 +40,8 @@ static void sirfsoc_secondary_init(unsigned int cpu)
spin_unlock(&boot_lock);
}
-static struct of_device_id rsc_ids[] = {
- { .compatible = "sirf,marco-rsc" },
+static struct of_device_id clk_ids[] = {
+ { .compatible = "sirf,atlas7-clkc" },
{},
};
@@ -70,27 +50,27 @@ static int sirfsoc_boot_secondary(unsigned int cpu, struct task_struct *idle)
unsigned long timeout;
struct device_node *np;
- np = of_find_matching_node(NULL, rsc_ids);
+ np = of_find_matching_node(NULL, clk_ids);
if (!np)
return -ENODEV;
- rsc_base = of_iomap(np, 0);
- if (!rsc_base)
+ clk_base = of_iomap(np, 0);
+ if (!clk_base)
return -ENOMEM;
/*
- * write the address of secondary startup into the sram register
- * at offset 0x2C, then write the magic number 0x3CAF5D62 to the
- * RSC register at offset 0x28, which is what boot rom code is
+ * write the address of secondary startup into the clkc register
+ * at offset 0x2bC, then write the magic number 0x3CAF5D62 to the
+ * clkc register at offset 0x2b8, which is what boot rom code is
* waiting for. This would wake up the secondary core from WFE
*/
-#define SIRFSOC_CPU1_JUMPADDR_OFFSET 0x2C
+#define SIRFSOC_CPU1_JUMPADDR_OFFSET 0x2bc
__raw_writel(virt_to_phys(sirfsoc_secondary_startup),
- rsc_base + SIRFSOC_CPU1_JUMPADDR_OFFSET);
+ clk_base + SIRFSOC_CPU1_JUMPADDR_OFFSET);
-#define SIRFSOC_CPU1_WAKEMAGIC_OFFSET 0x28
+#define SIRFSOC_CPU1_WAKEMAGIC_OFFSET 0x2b8
__raw_writel(0x3CAF5D62,
- rsc_base + SIRFSOC_CPU1_WAKEMAGIC_OFFSET);
+ clk_base + SIRFSOC_CPU1_WAKEMAGIC_OFFSET);
/* make sure write buffer is drained */
mb();
@@ -132,13 +112,7 @@ static int sirfsoc_boot_secondary(unsigned int cpu, struct task_struct *idle)
return pen_release != -1 ? -ENOSYS : 0;
}
-static void __init sirfsoc_smp_prepare_cpus(unsigned int max_cpus)
-{
- scu_enable(scu_base);
-}
-
struct smp_operations sirfsoc_smp_ops __initdata = {
- .smp_prepare_cpus = sirfsoc_smp_prepare_cpus,
.smp_secondary_init = sirfsoc_secondary_init,
.smp_boot_secondary = sirfsoc_boot_secondary,
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/arm/mach-prima2/rstc.c b/arch/arm/mach-prima2/rstc.c
index e1f1f86f6a95..7c251eb11d01 100644
--- a/arch/arm/mach-prima2/rstc.c
+++ b/arch/arm/mach-prima2/rstc.c
@@ -34,36 +34,20 @@ static int sirfsoc_reset_module(struct reset_controller_dev *rcdev,
mutex_lock(&rstc_lock);
- if (of_device_is_compatible(rcdev->of_node, "sirf,prima2-rstc")) {
- /*
- * Writing 1 to this bit resets corresponding block.
- * Writing 0 to this bit de-asserts reset signal of the
- * corresponding block. datasheet doesn't require explicit
- * delay between the set and clear of reset bit. it could
- * be shorter if tests pass.
- */
- writel(readl(sirfsoc_rstc_base +
+ /*
+ * Writing 1 to this bit resets corresponding block.
+ * Writing 0 to this bit de-asserts reset signal of the
+ * corresponding block. datasheet doesn't require explicit
+ * delay between the set and clear of reset bit. it could
+ * be shorter if tests pass.
+ */
+ writel(readl(sirfsoc_rstc_base +
(reset_bit / 32) * 4) | (1 << reset_bit),
- sirfsoc_rstc_base + (reset_bit / 32) * 4);
- msleep(20);
- writel(readl(sirfsoc_rstc_base +
+ sirfsoc_rstc_base + (reset_bit / 32) * 4);
+ msleep(20);
+ writel(readl(sirfsoc_rstc_base +
(reset_bit / 32) * 4) & ~(1 << reset_bit),
- sirfsoc_rstc_base + (reset_bit / 32) * 4);
- } else {
- /*
- * For MARCO and POLO
- * Writing 1 to SET register resets corresponding block.
- * Writing 1 to CLEAR register de-asserts reset signal of the
- * corresponding block.
- * datasheet doesn't require explicit delay between the set and
- * clear of reset bit. it could be shorter if tests pass.
- */
- writel(1 << reset_bit,
- sirfsoc_rstc_base + (reset_bit / 32) * 8);
- msleep(20);
- writel(1 << reset_bit,
- sirfsoc_rstc_base + (reset_bit / 32) * 8 + 4);
- }
+ sirfsoc_rstc_base + (reset_bit / 32) * 4);
mutex_unlock(&rstc_lock);
@@ -106,7 +90,6 @@ static int sirfsoc_rstc_probe(struct platform_device *pdev)
static const struct of_device_id rstc_ids[] = {
{ .compatible = "sirf,prima2-rstc" },
- { .compatible = "sirf,marco-rstc" },
{},
};
diff --git a/arch/arm/mach-prima2/rtciobrg.c b/arch/arm/mach-prima2/rtciobrg.c
index 70a0b475062b..8f66d8f7ca75 100644
--- a/arch/arm/mach-prima2/rtciobrg.c
+++ b/arch/arm/mach-prima2/rtciobrg.c
@@ -104,7 +104,6 @@ EXPORT_SYMBOL_GPL(sirfsoc_rtc_iobrg_writel);
static const struct of_device_id rtciobrg_ids[] = {
{ .compatible = "sirf,prima2-rtciobg" },
- { .compatible = "sirf,marco-rtciobg" },
{}
};
diff --git a/arch/arm/mach-pxa/Kconfig b/arch/arm/mach-pxa/Kconfig
index 83efe914bf7d..8896e71586f5 100644
--- a/arch/arm/mach-pxa/Kconfig
+++ b/arch/arm/mach-pxa/Kconfig
@@ -6,7 +6,6 @@ comment "Intel/Marvell Dev Platforms (sorted by hardware release time)"
config MACH_PXA27X_DT
bool "Support PXA27x platforms from device tree"
- select CPU_PXA27x
select POWER_SUPPLY
select PXA27x
select USE_OF
@@ -84,14 +83,12 @@ config ARCH_VIPER
select I2C_GPIO if I2C=y
select ISA
select PXA25x
- select PXA_HAVE_ISA_IRQS
config MACH_ARCOM_ZEUS
bool "Arcom/Eurotech ZEUS SBC"
select ARCOM_PCMCIA
select ISA
select PXA27x
- select PXA_HAVE_ISA_IRQS
config MACH_BALLOON3
bool "Balloon 3 board"
@@ -691,9 +688,6 @@ config SHARPSL_PM_MAX1111
select SPI
select SPI_MASTER
-config PXA_HAVE_ISA_IRQS
- bool
-
config PXA310_ULPI
bool
diff --git a/arch/arm/mach-pxa/corgi.c b/arch/arm/mach-pxa/corgi.c
index 06022b235730..89f790dda93e 100644
--- a/arch/arm/mach-pxa/corgi.c
+++ b/arch/arm/mach-pxa/corgi.c
@@ -26,6 +26,7 @@
#include <linux/i2c.h>
#include <linux/i2c/pxa-i2c.h>
#include <linux/io.h>
+#include <linux/regulator/machine.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/spi/corgi_lcd.h>
@@ -752,6 +753,8 @@ static void __init corgi_init(void)
sharpsl_nand_partitions[1].size = 53 * 1024 * 1024;
platform_add_devices(devices, ARRAY_SIZE(devices));
+
+ regulator_has_full_constraints();
}
static void __init fixup_corgi(struct tag *tags, char **cmdline)
diff --git a/arch/arm/mach-pxa/devices.c b/arch/arm/mach-pxa/devices.c
index ac7b3eabbd85..35434662dc7c 100644
--- a/arch/arm/mach-pxa/devices.c
+++ b/arch/arm/mach-pxa/devices.c
@@ -40,7 +40,7 @@ static struct resource pxa_resource_pmu = {
};
struct platform_device pxa_device_pmu = {
- .name = "arm-pmu",
+ .name = "xscale-pmu",
.id = -1,
.resource = &pxa_resource_pmu,
.num_resources = 1,
diff --git a/arch/arm/mach-pxa/hx4700.c b/arch/arm/mach-pxa/hx4700.c
index c66ad4edc5e3..5fb41ad6e3bc 100644
--- a/arch/arm/mach-pxa/hx4700.c
+++ b/arch/arm/mach-pxa/hx4700.c
@@ -893,6 +893,8 @@ static void __init hx4700_init(void)
mdelay(10);
gpio_set_value(GPIO71_HX4700_ASIC3_nRESET, 1);
mdelay(10);
+
+ regulator_has_full_constraints();
}
MACHINE_START(H4700, "HP iPAQ HX4700")
diff --git a/arch/arm/mach-pxa/include/mach/irqs.h b/arch/arm/mach-pxa/include/mach/irqs.h
index 48c2fd851686..7e3ea351f3c7 100644
--- a/arch/arm/mach-pxa/include/mach/irqs.h
+++ b/arch/arm/mach-pxa/include/mach/irqs.h
@@ -12,14 +12,10 @@
#ifndef __ASM_MACH_IRQS_H
#define __ASM_MACH_IRQS_H
-#ifdef CONFIG_PXA_HAVE_ISA_IRQS
-#define PXA_ISA_IRQ(x) (x)
-#define PXA_ISA_IRQ_NUM (16)
-#else
-#define PXA_ISA_IRQ_NUM (0)
-#endif
+#include <asm/irq.h>
-#define PXA_IRQ(x) (PXA_ISA_IRQ_NUM + (x))
+#define PXA_ISA_IRQ(x) (x)
+#define PXA_IRQ(x) (NR_IRQS_LEGACY + (x))
#define IRQ_SSP3 PXA_IRQ(0) /* SSP3 service request */
#define IRQ_MSL PXA_IRQ(1) /* MSL Interface interrupt */
diff --git a/arch/arm/mach-pxa/poodle.c b/arch/arm/mach-pxa/poodle.c
index 29019beae591..195b1121c8f1 100644
--- a/arch/arm/mach-pxa/poodle.c
+++ b/arch/arm/mach-pxa/poodle.c
@@ -25,6 +25,7 @@
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/i2c/pxa-i2c.h>
+#include <linux/regulator/machine.h>
#include <linux/spi/spi.h>
#include <linux/spi/ads7846.h>
#include <linux/spi/pxa2xx_spi.h>
@@ -455,6 +456,7 @@ static void __init poodle_init(void)
pxa_set_i2c_info(NULL);
i2c_register_board_info(0, ARRAY_AND_SIZE(poodle_i2c_devices));
poodle_init_spi();
+ regulator_has_full_constraints();
}
static void __init fixup_poodle(struct tag *tags, char **cmdline)
diff --git a/arch/arm/mach-pxa/spitz.c b/arch/arm/mach-pxa/spitz.c
index 962a7f31f596..f4e2e2719580 100644
--- a/arch/arm/mach-pxa/spitz.c
+++ b/arch/arm/mach-pxa/spitz.c
@@ -979,6 +979,8 @@ static void __init spitz_init(void)
spitz_nand_init();
spitz_i2c_init();
spitz_audio_init();
+
+ regulator_has_full_constraints();
}
static void __init spitz_fixup(struct tag *tags, char **cmdline)
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig
index ee5697ba05bc..48003ea652b9 100644
--- a/arch/arm/mach-qcom/Kconfig
+++ b/arch/arm/mach-qcom/Kconfig
@@ -1,9 +1,8 @@
menuconfig ARCH_QCOM
bool "Qualcomm Support" if ARCH_MULTI_V7
- select ARCH_REQUIRE_GPIOLIB
+ select ARCH_SUPPORTS_BIG_ENDIAN
select ARM_GIC
select ARM_AMBA
- select CLKSRC_OF
select PINCTRL
select QCOM_SCM if SMP
help
diff --git a/arch/arm/mach-qcom/platsmp.c b/arch/arm/mach-qcom/platsmp.c
index d6908569ecaf..09cffed4c0a4 100644
--- a/arch/arm/mach-qcom/platsmp.c
+++ b/arch/arm/mach-qcom/platsmp.c
@@ -44,7 +44,7 @@
#define APCS_SAW2_VCTL 0x14
#define APCS_SAW2_2_VCTL 0x1c
-extern void secondary_startup(void);
+extern void secondary_startup_arm(void);
static DEFINE_SPINLOCK(boot_lock);
@@ -337,7 +337,7 @@ static void __init qcom_smp_prepare_cpus(unsigned int max_cpus)
flags |= cold_boot_flags[map];
}
- if (scm_set_boot_addr(virt_to_phys(secondary_startup), flags)) {
+ if (scm_set_boot_addr(virt_to_phys(secondary_startup_arm), flags)) {
for_each_present_cpu(cpu) {
if (cpu == smp_processor_id())
continue;
diff --git a/arch/arm/mach-qcom/scm-boot.c b/arch/arm/mach-qcom/scm-boot.c
index 45cee3e469a5..e8ff7beb6218 100644
--- a/arch/arm/mach-qcom/scm-boot.c
+++ b/arch/arm/mach-qcom/scm-boot.c
@@ -24,15 +24,15 @@
/*
* Set the cold/warm boot address for one of the CPU cores.
*/
-int scm_set_boot_addr(phys_addr_t addr, int flags)
+int scm_set_boot_addr(u32 addr, int flags)
{
struct {
- unsigned int flags;
- phys_addr_t addr;
+ __le32 flags;
+ __le32 addr;
} cmd;
- cmd.addr = addr;
- cmd.flags = flags;
+ cmd.addr = cpu_to_le32(addr);
+ cmd.flags = cpu_to_le32(flags);
return scm_call(SCM_SVC_BOOT, SCM_BOOT_ADDR,
&cmd, sizeof(cmd), NULL, 0);
}
diff --git a/arch/arm/mach-qcom/scm-boot.h b/arch/arm/mach-qcom/scm-boot.h
index 6aabb2428176..3e210fb818bb 100644
--- a/arch/arm/mach-qcom/scm-boot.h
+++ b/arch/arm/mach-qcom/scm-boot.h
@@ -18,7 +18,9 @@
#define SCM_FLAG_COLDBOOT_CPU3 0x20
#define SCM_FLAG_WARMBOOT_CPU0 0x04
#define SCM_FLAG_WARMBOOT_CPU1 0x02
+#define SCM_FLAG_WARMBOOT_CPU2 0x10
+#define SCM_FLAG_WARMBOOT_CPU3 0x40
-int scm_set_boot_addr(phys_addr_t addr, int flags);
+int scm_set_boot_addr(u32 addr, int flags);
#endif
diff --git a/arch/arm/mach-qcom/scm.c b/arch/arm/mach-qcom/scm.c
index c536fd6bf827..1d9cf18c7091 100644
--- a/arch/arm/mach-qcom/scm.c
+++ b/arch/arm/mach-qcom/scm.c
@@ -22,13 +22,11 @@
#include <linux/errno.h>
#include <linux/err.h>
+#include <asm/outercache.h>
#include <asm/cacheflush.h>
#include "scm.h"
-/* Cache line size for msm8x60 */
-#define CACHELINESIZE 32
-
#define SCM_ENOMEM -5
#define SCM_EOPNOTSUPP -4
#define SCM_EINVAL_ADDR -3
@@ -63,11 +61,11 @@ static DEFINE_MUTEX(scm_lock);
* to access the buffers in a safe manner.
*/
struct scm_command {
- u32 len;
- u32 buf_offset;
- u32 resp_hdr_offset;
- u32 id;
- u32 buf[0];
+ __le32 len;
+ __le32 buf_offset;
+ __le32 resp_hdr_offset;
+ __le32 id;
+ __le32 buf[0];
};
/**
@@ -77,9 +75,9 @@ struct scm_command {
* @is_complete: indicates if the command has finished processing
*/
struct scm_response {
- u32 len;
- u32 buf_offset;
- u32 is_complete;
+ __le32 len;
+ __le32 buf_offset;
+ __le32 is_complete;
};
/**
@@ -97,12 +95,14 @@ static struct scm_command *alloc_scm_command(size_t cmd_size, size_t resp_size)
struct scm_command *cmd;
size_t len = sizeof(*cmd) + sizeof(struct scm_response) + cmd_size +
resp_size;
+ u32 offset;
cmd = kzalloc(PAGE_ALIGN(len), GFP_KERNEL);
if (cmd) {
- cmd->len = len;
- cmd->buf_offset = offsetof(struct scm_command, buf);
- cmd->resp_hdr_offset = cmd->buf_offset + cmd_size;
+ cmd->len = cpu_to_le32(len);
+ offset = offsetof(struct scm_command, buf);
+ cmd->buf_offset = cpu_to_le32(offset);
+ cmd->resp_hdr_offset = cpu_to_le32(offset + cmd_size);
}
return cmd;
}
@@ -127,7 +127,7 @@ static inline void free_scm_command(struct scm_command *cmd)
static inline struct scm_response *scm_command_to_response(
const struct scm_command *cmd)
{
- return (void *)cmd + cmd->resp_hdr_offset;
+ return (void *)cmd + le32_to_cpu(cmd->resp_hdr_offset);
}
/**
@@ -149,11 +149,12 @@ static inline void *scm_get_command_buffer(const struct scm_command *cmd)
*/
static inline void *scm_get_response_buffer(const struct scm_response *rsp)
{
- return (void *)rsp + rsp->buf_offset;
+ return (void *)rsp + le32_to_cpu(rsp->buf_offset);
}
static int scm_remap_error(int err)
{
+ pr_err("scm_call failed with error code %d\n", err);
switch (err) {
case SCM_ERROR:
return -EIO;
@@ -198,11 +199,12 @@ static int __scm_call(const struct scm_command *cmd)
u32 cmd_addr = virt_to_phys(cmd);
/*
- * Flush the entire cache here so callers don't have to remember
- * to flush the cache when passing physical addresses to the secure
- * side in the buffer.
+ * Flush the command buffer so that the secure world sees
+ * the correct data.
*/
- flush_cache_all();
+ __cpuc_flush_dcache_area((void *)cmd, cmd->len);
+ outer_flush_range(cmd_addr, cmd_addr + cmd->len);
+
ret = smc(cmd_addr);
if (ret < 0)
ret = scm_remap_error(ret);
@@ -210,6 +212,25 @@ static int __scm_call(const struct scm_command *cmd)
return ret;
}
+static void scm_inv_range(unsigned long start, unsigned long end)
+{
+ u32 cacheline_size, ctr;
+
+ asm volatile("mrc p15, 0, %0, c0, c0, 1" : "=r" (ctr));
+ cacheline_size = 4 << ((ctr >> 16) & 0xf);
+
+ start = round_down(start, cacheline_size);
+ end = round_up(end, cacheline_size);
+ outer_inv_range(start, end);
+ while (start < end) {
+ asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
+ : "memory");
+ start += cacheline_size;
+ }
+ dsb();
+ isb();
+}
+
/**
* scm_call() - Send an SCM command
* @svc_id: service identifier
@@ -220,6 +241,13 @@ static int __scm_call(const struct scm_command *cmd)
* @resp_len: length of the response buffer
*
* Sends a command to the SCM and waits for the command to finish processing.
+ *
+ * A note on cache maintenance:
+ * Note that any buffers that are expected to be accessed by the secure world
+ * must be flushed before invoking scm_call and invalidated in the cache
+ * immediately after scm_call returns. Cache maintenance on the command and
+ * response buffers is taken care of by scm_call; however, callers are
+ * responsible for any other cached buffers passed over to the secure world.
*/
int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
void *resp_buf, size_t resp_len)
@@ -227,12 +255,13 @@ int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
int ret;
struct scm_command *cmd;
struct scm_response *rsp;
+ unsigned long start, end;
cmd = alloc_scm_command(cmd_len, resp_len);
if (!cmd)
return -ENOMEM;
- cmd->id = (svc_id << 10) | cmd_id;
+ cmd->id = cpu_to_le32((svc_id << 10) | cmd_id);
if (cmd_buf)
memcpy(scm_get_command_buffer(cmd), cmd_buf, cmd_len);
@@ -243,17 +272,15 @@ int scm_call(u32 svc_id, u32 cmd_id, const void *cmd_buf, size_t cmd_len,
goto out;
rsp = scm_command_to_response(cmd);
+ start = (unsigned long)rsp;
+
do {
- u32 start = (u32)rsp;
- u32 end = (u32)scm_get_response_buffer(rsp) + resp_len;
- start &= ~(CACHELINESIZE - 1);
- while (start < end) {
- asm ("mcr p15, 0, %0, c7, c6, 1" : : "r" (start)
- : "memory");
- start += CACHELINESIZE;
- }
+ scm_inv_range(start, start + sizeof(*rsp));
} while (!rsp->is_complete);
+ end = (unsigned long)scm_get_response_buffer(rsp) + resp_len;
+ scm_inv_range(start, end);
+
if (resp_buf)
memcpy(resp_buf, scm_get_response_buffer(rsp), resp_len);
out:
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 739d4f113097..64c88d657f9e 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -37,6 +37,7 @@
#include <asm/pgtable.h>
#include <asm/hardware/cache-l2x0.h>
#include <asm/smp_twd.h>
+#include <asm/system_info.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
@@ -296,7 +297,6 @@ static struct resource pmu_resources[] = {
};
static struct platform_device pmu_device = {
- .name = "arm-pmu",
.id = -1,
.num_resources = ARRAY_SIZE(pmu_resources),
.resource = pmu_resources,
@@ -451,6 +451,7 @@ static void __init realview_eb_init(void)
*/
l2x0_init(__io_address(REALVIEW_EB11MP_L220_BASE), 0x00790000, 0xfe000fff);
#endif
+ pmu_device.name = core_tile_a9mp() ? "armv7-pmu" : "armv6-pmu";
platform_device_register(&pmu_device);
}
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index b0e0dcaed944..ce92c1823494 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -280,7 +280,7 @@ static struct resource pmu_resource = {
};
static struct platform_device pmu_device = {
- .name = "arm-pmu",
+ .name = "armv6-pmu",
.id = -1,
.num_resources = 1,
.resource = &pmu_resource,
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index 47bf55fdbf27..15c45e25095f 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -262,7 +262,7 @@ static struct resource pmu_resources[] = {
};
static struct platform_device pmu_device = {
- .name = "arm-pmu",
+ .name = "armv6-pmu",
.id = -1,
.num_resources = ARRAY_SIZE(pmu_resources),
.resource = pmu_resources,
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index 4e57a8599265..4c64662f5437 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -240,7 +240,7 @@ static struct resource pmu_resource = {
};
static struct platform_device pmu_device = {
- .name = "arm-pmu",
+ .name = "armv7-pmu",
.id = -1,
.num_resources = 1,
.resource = &pmu_resource,
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index d89eb4023467..9a22b864219f 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -280,7 +280,7 @@ static struct resource pmu_resources[] = {
};
static struct platform_device pmu_device = {
- .name = "arm-pmu",
+ .name = "armv7-pmu",
.id = -1,
.num_resources = ARRAY_SIZE(pmu_resources),
.resource = pmu_resources,
diff --git a/arch/arm/mach-rockchip/Kconfig b/arch/arm/mach-rockchip/Kconfig
index ac5803cac98d..5078932c1683 100644
--- a/arch/arm/mach-rockchip/Kconfig
+++ b/arch/arm/mach-rockchip/Kconfig
@@ -11,6 +11,7 @@ config ARCH_ROCKCHIP
select HAVE_ARM_SCU if SMP
select HAVE_ARM_TWD if SMP
select DW_APB_TIMER_OF
+ select ROCKCHIP_TIMER
select ARM_GLOBAL_TIMER
select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK
help
diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile
index b29d8ead4cf2..5c3a9b2de920 100644
--- a/arch/arm/mach-rockchip/Makefile
+++ b/arch/arm/mach-rockchip/Makefile
@@ -1,4 +1,5 @@
CFLAGS_platsmp.o := -march=armv7-a
obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip.o
+obj-$(CONFIG_PM_SLEEP) += pm.o sleep.o
obj-$(CONFIG_SMP) += headsmp.o platsmp.o
diff --git a/arch/arm/mach-rockchip/pm.c b/arch/arm/mach-rockchip/pm.c
new file mode 100644
index 000000000000..50cb781aaa36
--- /dev/null
+++ b/arch/arm/mach-rockchip/pm.c
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Tony Xie <tony.xie@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/regmap.h>
+#include <linux/suspend.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regulator/machine.h>
+
+#include <asm/cacheflush.h>
+#include <asm/tlbflush.h>
+#include <asm/suspend.h>
+
+#include "pm.h"
+
+/* These enum are option of low power mode */
+enum {
+ ROCKCHIP_ARM_OFF_LOGIC_NORMAL = 0,
+ ROCKCHIP_ARM_OFF_LOGIC_DEEP = 1,
+};
+
+struct rockchip_pm_data {
+ const struct platform_suspend_ops *ops;
+ int (*init)(struct device_node *np);
+};
+
+static void __iomem *rk3288_bootram_base;
+static phys_addr_t rk3288_bootram_phy;
+
+static struct regmap *pmu_regmap;
+static struct regmap *sgrf_regmap;
+
+static u32 rk3288_pmu_pwr_mode_con;
+static u32 rk3288_sgrf_soc_con0;
+
+static inline u32 rk3288_l2_config(void)
+{
+ u32 l2ctlr;
+
+ asm("mrc p15, 1, %0, c9, c0, 2" : "=r" (l2ctlr));
+ return l2ctlr;
+}
+
+static void rk3288_config_bootdata(void)
+{
+ rkpm_bootdata_cpusp = rk3288_bootram_phy + (SZ_4K - 8);
+ rkpm_bootdata_cpu_code = virt_to_phys(cpu_resume);
+
+ rkpm_bootdata_l2ctlr_f = 1;
+ rkpm_bootdata_l2ctlr = rk3288_l2_config();
+}
+
+static void rk3288_slp_mode_set(int level)
+{
+ u32 mode_set, mode_set1;
+
+ regmap_read(sgrf_regmap, RK3288_SGRF_SOC_CON0, &rk3288_sgrf_soc_con0);
+
+ regmap_read(pmu_regmap, RK3288_PMU_PWRMODE_CON,
+ &rk3288_pmu_pwr_mode_con);
+
+ /* set bit 8 so that system will resume to FAST_BOOT_ADDR */
+ regmap_write(sgrf_regmap, RK3288_SGRF_SOC_CON0,
+ SGRF_FAST_BOOT_EN | SGRF_FAST_BOOT_EN_WRITE);
+
+ /* booting address of resuming system is from this register value */
+ regmap_write(sgrf_regmap, RK3288_SGRF_FAST_BOOT_ADDR,
+ rk3288_bootram_phy);
+
+ regmap_write(pmu_regmap, RK3288_PMU_WAKEUP_CFG1,
+ PMU_ARMINT_WAKEUP_EN);
+
+ mode_set = BIT(PMU_GLOBAL_INT_DISABLE) | BIT(PMU_L2FLUSH_EN) |
+ BIT(PMU_SREF0_ENTER_EN) | BIT(PMU_SREF1_ENTER_EN) |
+ BIT(PMU_DDR0_GATING_EN) | BIT(PMU_DDR1_GATING_EN) |
+ BIT(PMU_PWR_MODE_EN) | BIT(PMU_CHIP_PD_EN) |
+ BIT(PMU_SCU_EN);
+
+ mode_set1 = BIT(PMU_CLR_CORE) | BIT(PMU_CLR_CPUP);
+
+ if (level == ROCKCHIP_ARM_OFF_LOGIC_DEEP) {
+ /* arm off, logic deep sleep */
+ mode_set |= BIT(PMU_BUS_PD_EN) |
+ BIT(PMU_DDR1IO_RET_EN) | BIT(PMU_DDR0IO_RET_EN) |
+ BIT(PMU_OSC_24M_DIS) | BIT(PMU_PMU_USE_LF) |
+ BIT(PMU_ALIVE_USE_LF) | BIT(PMU_PLL_PD_EN);
+
+ mode_set1 |= BIT(PMU_CLR_ALIVE) | BIT(PMU_CLR_BUS) |
+ BIT(PMU_CLR_PERI) | BIT(PMU_CLR_DMA);
+ } else {
+ /*
+ * arm off, logic normal
+ * if pmu_clk_core_src_gate_en is not set,
+ * wakeup will be error
+ */
+ mode_set |= BIT(PMU_CLK_CORE_SRC_GATE_EN);
+ }
+
+ regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON, mode_set);
+ regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON1, mode_set1);
+}
+
+static void rk3288_slp_mode_set_resume(void)
+{
+ regmap_write(pmu_regmap, RK3288_PMU_PWRMODE_CON,
+ rk3288_pmu_pwr_mode_con);
+
+ regmap_write(sgrf_regmap, RK3288_SGRF_SOC_CON0,
+ rk3288_sgrf_soc_con0 | SGRF_FAST_BOOT_EN_WRITE);
+}
+
+static int rockchip_lpmode_enter(unsigned long arg)
+{
+ flush_cache_all();
+
+ cpu_do_idle();
+
+ pr_err("%s: Failed to suspend\n", __func__);
+
+ return 1;
+}
+
+static int rk3288_suspend_enter(suspend_state_t state)
+{
+ local_fiq_disable();
+
+ rk3288_slp_mode_set(ROCKCHIP_ARM_OFF_LOGIC_NORMAL);
+
+ cpu_suspend(0, rockchip_lpmode_enter);
+
+ rk3288_slp_mode_set_resume();
+
+ local_fiq_enable();
+
+ return 0;
+}
+
+static int rk3288_suspend_prepare(void)
+{
+ return regulator_suspend_prepare(PM_SUSPEND_MEM);
+}
+
+static void rk3288_suspend_finish(void)
+{
+ if (regulator_suspend_finish())
+ pr_err("%s: Suspend finish failed\n", __func__);
+}
+
+static int rk3288_suspend_init(struct device_node *np)
+{
+ struct device_node *sram_np;
+ struct resource res;
+ int ret;
+
+ pmu_regmap = syscon_node_to_regmap(np);
+ if (IS_ERR(pmu_regmap)) {
+ pr_err("%s: could not find pmu regmap\n", __func__);
+ return PTR_ERR(pmu_regmap);
+ }
+
+ sgrf_regmap = syscon_regmap_lookup_by_compatible(
+ "rockchip,rk3288-sgrf");
+ if (IS_ERR(sgrf_regmap)) {
+ pr_err("%s: could not find sgrf regmap\n", __func__);
+ return PTR_ERR(pmu_regmap);
+ }
+
+ sram_np = of_find_compatible_node(NULL, NULL,
+ "rockchip,rk3288-pmu-sram");
+ if (!sram_np) {
+ pr_err("%s: could not find bootram dt node\n", __func__);
+ return -ENODEV;
+ }
+
+ rk3288_bootram_base = of_iomap(sram_np, 0);
+ if (!rk3288_bootram_base) {
+ pr_err("%s: could not map bootram base\n", __func__);
+ return -ENOMEM;
+ }
+
+ ret = of_address_to_resource(sram_np, 0, &res);
+ if (ret) {
+ pr_err("%s: could not get bootram phy addr\n", __func__);
+ return ret;
+ }
+ rk3288_bootram_phy = res.start;
+
+ of_node_put(sram_np);
+
+ rk3288_config_bootdata();
+
+ /* copy resume code and data to bootsram */
+ memcpy(rk3288_bootram_base, rockchip_slp_cpu_resume,
+ rk3288_bootram_sz);
+
+ return 0;
+}
+
+static const struct platform_suspend_ops rk3288_suspend_ops = {
+ .enter = rk3288_suspend_enter,
+ .valid = suspend_valid_only_mem,
+ .prepare = rk3288_suspend_prepare,
+ .finish = rk3288_suspend_finish,
+};
+
+static const struct rockchip_pm_data rk3288_pm_data __initconst = {
+ .ops = &rk3288_suspend_ops,
+ .init = rk3288_suspend_init,
+};
+
+static const struct of_device_id rockchip_pmu_of_device_ids[] __initconst = {
+ {
+ .compatible = "rockchip,rk3288-pmu",
+ .data = &rk3288_pm_data,
+ },
+ { /* sentinel */ },
+};
+
+void __init rockchip_suspend_init(void)
+{
+ const struct rockchip_pm_data *pm_data;
+ const struct of_device_id *match;
+ struct device_node *np;
+ int ret;
+
+ np = of_find_matching_node_and_match(NULL, rockchip_pmu_of_device_ids,
+ &match);
+ if (!match) {
+ pr_err("Failed to find PMU node\n");
+ return;
+ }
+ pm_data = (struct rockchip_pm_data *) match->data;
+
+ if (pm_data->init) {
+ ret = pm_data->init(np);
+
+ if (ret) {
+ pr_err("%s: matches init error %d\n", __func__, ret);
+ return;
+ }
+ }
+
+ suspend_set_ops(pm_data->ops);
+}
diff --git a/arch/arm/mach-rockchip/pm.h b/arch/arm/mach-rockchip/pm.h
new file mode 100644
index 000000000000..7d752ff39f91
--- /dev/null
+++ b/arch/arm/mach-rockchip/pm.h
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Tony Xie <tony.xie@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef __MACH_ROCKCHIP_PM_H
+#define __MACH_ROCKCHIP_PM_H
+
+extern unsigned long rkpm_bootdata_cpusp;
+extern unsigned long rkpm_bootdata_cpu_code;
+extern unsigned long rkpm_bootdata_l2ctlr_f;
+extern unsigned long rkpm_bootdata_l2ctlr;
+extern unsigned long rkpm_bootdata_ddr_code;
+extern unsigned long rkpm_bootdata_ddr_data;
+extern unsigned long rk3288_bootram_sz;
+
+void rockchip_slp_cpu_resume(void);
+void __init rockchip_suspend_init(void);
+
+/****** following is rk3288 defined **********/
+#define RK3288_PMU_WAKEUP_CFG0 0x00
+#define RK3288_PMU_WAKEUP_CFG1 0x04
+#define RK3288_PMU_PWRMODE_CON 0x18
+#define RK3288_PMU_OSC_CNT 0x20
+#define RK3288_PMU_PLL_CNT 0x24
+#define RK3288_PMU_STABL_CNT 0x28
+#define RK3288_PMU_DDR0IO_PWRON_CNT 0x2c
+#define RK3288_PMU_DDR1IO_PWRON_CNT 0x30
+#define RK3288_PMU_CORE_PWRDWN_CNT 0x34
+#define RK3288_PMU_CORE_PWRUP_CNT 0x38
+#define RK3288_PMU_GPU_PWRDWN_CNT 0x3c
+#define RK3288_PMU_GPU_PWRUP_CNT 0x40
+#define RK3288_PMU_WAKEUP_RST_CLR_CNT 0x44
+#define RK3288_PMU_PWRMODE_CON1 0x90
+
+#define RK3288_SGRF_SOC_CON0 (0x0000)
+#define RK3288_SGRF_FAST_BOOT_ADDR (0x0120)
+#define SGRF_FAST_BOOT_EN BIT(8)
+#define SGRF_FAST_BOOT_EN_WRITE BIT(24)
+
+#define RK3288_CRU_MODE_CON 0x50
+#define RK3288_CRU_SEL0_CON 0x60
+#define RK3288_CRU_SEL1_CON 0x64
+#define RK3288_CRU_SEL10_CON 0x88
+#define RK3288_CRU_SEL33_CON 0xe4
+#define RK3288_CRU_SEL37_CON 0xf4
+
+/* PMU_WAKEUP_CFG1 bits */
+#define PMU_ARMINT_WAKEUP_EN BIT(0)
+
+enum rk3288_pwr_mode_con {
+ PMU_PWR_MODE_EN = 0,
+ PMU_CLK_CORE_SRC_GATE_EN,
+ PMU_GLOBAL_INT_DISABLE,
+ PMU_L2FLUSH_EN,
+ PMU_BUS_PD_EN,
+ PMU_A12_0_PD_EN,
+ PMU_SCU_EN,
+ PMU_PLL_PD_EN,
+ PMU_CHIP_PD_EN, /* POWER OFF PIN ENABLE */
+ PMU_PWROFF_COMB,
+ PMU_ALIVE_USE_LF,
+ PMU_PMU_USE_LF,
+ PMU_OSC_24M_DIS,
+ PMU_INPUT_CLAMP_EN,
+ PMU_WAKEUP_RESET_EN,
+ PMU_SREF0_ENTER_EN,
+ PMU_SREF1_ENTER_EN,
+ PMU_DDR0IO_RET_EN,
+ PMU_DDR1IO_RET_EN,
+ PMU_DDR0_GATING_EN,
+ PMU_DDR1_GATING_EN,
+ PMU_DDR0IO_RET_DE_REQ,
+ PMU_DDR1IO_RET_DE_REQ
+};
+
+enum rk3288_pwr_mode_con1 {
+ PMU_CLR_BUS = 0,
+ PMU_CLR_CORE,
+ PMU_CLR_CPUP,
+ PMU_CLR_ALIVE,
+ PMU_CLR_DMA,
+ PMU_CLR_PERI,
+ PMU_CLR_GPU,
+ PMU_CLR_VIDEO,
+ PMU_CLR_HEVC,
+ PMU_CLR_VIO,
+};
+
+#endif /* __MACH_ROCKCHIP_PM_H */
diff --git a/arch/arm/mach-rockchip/rockchip.c b/arch/arm/mach-rockchip/rockchip.c
index d226b71d21d5..d360ec044b66 100644
--- a/arch/arm/mach-rockchip/rockchip.c
+++ b/arch/arm/mach-rockchip/rockchip.c
@@ -19,13 +19,41 @@
#include <linux/init.h>
#include <linux/of_platform.h>
#include <linux/irqchip.h>
+#include <linux/clk-provider.h>
+#include <linux/clocksource.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
#include <asm/mach/arch.h>
#include <asm/mach/map.h>
#include <asm/hardware/cache-l2x0.h>
#include "core.h"
+#include "pm.h"
+
+#define RK3288_GRF_SOC_CON0 0x244
+
+static void __init rockchip_timer_init(void)
+{
+ if (of_machine_is_compatible("rockchip,rk3288")) {
+ struct regmap *grf;
+
+ /*
+ * Disable auto jtag/sdmmc switching that causes issues
+ * with the mmc controllers making them unreliable
+ */
+ grf = syscon_regmap_lookup_by_compatible("rockchip,rk3288-grf");
+ if (!IS_ERR(grf))
+ regmap_write(grf, RK3288_GRF_SOC_CON0, 0x10000000);
+ else
+ pr_err("rockchip: could not get grf syscon\n");
+ }
+
+ of_clk_init(NULL);
+ clocksource_of_init();
+}
static void __init rockchip_dt_init(void)
{
+ rockchip_suspend_init();
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
platform_device_register_simple("cpufreq-dt", 0, NULL, 0);
}
@@ -39,9 +67,10 @@ static const char * const rockchip_board_dt_compat[] = {
NULL,
};
-DT_MACHINE_START(ROCKCHIP_DT, "Rockchip Cortex-A9 (Device Tree)")
+DT_MACHINE_START(ROCKCHIP_DT, "Rockchip (Device Tree)")
.l2c_aux_val = 0,
.l2c_aux_mask = ~0,
+ .init_time = rockchip_timer_init,
.dt_compat = rockchip_board_dt_compat,
.init_machine = rockchip_dt_init,
MACHINE_END
diff --git a/arch/arm/mach-rockchip/sleep.S b/arch/arm/mach-rockchip/sleep.S
new file mode 100644
index 000000000000..2eec9a341f05
--- /dev/null
+++ b/arch/arm/mach-rockchip/sleep.S
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
+ * Author: Tony Xie <tony.xie@rock-chips.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <asm/memory.h>
+
+.data
+/*
+ * this code will be copied from
+ * ddr to sram for system resumeing.
+ * so it is ".data section".
+ */
+.align
+
+ENTRY(rockchip_slp_cpu_resume)
+ setmode PSR_I_BIT | PSR_F_BIT | SVC_MODE, r1 @ set svc, irqs off
+ mrc p15, 0, r1, c0, c0, 5
+ and r1, r1, #0xf
+ cmp r1, #0
+ /* olny cpu0 can continue to run, the others is halt here */
+ beq cpu0run
+secondary_loop:
+ wfe
+ b secondary_loop
+cpu0run:
+ ldr r3, rkpm_bootdata_l2ctlr_f
+ cmp r3, #0
+ beq sp_set
+ ldr r3, rkpm_bootdata_l2ctlr
+ mcr p15, 1, r3, c9, c0, 2
+sp_set:
+ ldr sp, rkpm_bootdata_cpusp
+ ldr r1, rkpm_bootdata_cpu_code
+ bx r1
+ENDPROC(rockchip_slp_cpu_resume)
+
+/* Parameters filled in by the kernel */
+
+/* Flag for whether to restore L2CTLR on resume */
+ .global rkpm_bootdata_l2ctlr_f
+rkpm_bootdata_l2ctlr_f:
+ .long 0
+
+/* Saved L2CTLR to restore on resume */
+ .global rkpm_bootdata_l2ctlr
+rkpm_bootdata_l2ctlr:
+ .long 0
+
+/* CPU resume SP addr */
+ .globl rkpm_bootdata_cpusp
+rkpm_bootdata_cpusp:
+ .long 0
+
+/* CPU resume function (physical address) */
+ .globl rkpm_bootdata_cpu_code
+rkpm_bootdata_cpu_code:
+ .long 0
+
+ENTRY(rk3288_bootram_sz)
+ .word . - rockchip_slp_cpu_resume
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig
index 9eb22297cbe1..79c49ff77f6e 100644
--- a/arch/arm/mach-s3c24xx/Kconfig
+++ b/arch/arm/mach-s3c24xx/Kconfig
@@ -29,7 +29,6 @@ config CPU_S3C2410
default y
select CPU_ARM920T
select S3C2410_COMMON_CLK
- select S3C2410_DMA if S3C24XX_DMA
select ARM_S3C2410_CPUFREQ if ARM_S3C24XX_CPUFREQ
select S3C2410_PM if PM
help
@@ -40,7 +39,6 @@ config CPU_S3C2412
bool "SAMSUNG S3C2412"
select CPU_ARM926T
select S3C2412_COMMON_CLK
- select S3C2412_DMA if S3C24XX_DMA
select S3C2412_PM if PM
help
Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
@@ -50,7 +48,6 @@ config CPU_S3C2416
select CPU_ARM926T
select S3C2416_PM if PM
select S3C2443_COMMON_CLK
- select S3C2443_DMA if S3C24XX_DMA
help
Support for the S3C2416 SoC from the S3C24XX line
@@ -59,7 +56,6 @@ config CPU_S3C2440
select CPU_ARM920T
select S3C2410_COMMON_CLK
select S3C2410_PM if PM
- select S3C2440_DMA if S3C24XX_DMA
help
Support for S3C2440 Samsung Mobile CPU based systems.
@@ -67,7 +63,6 @@ config CPU_S3C2442
bool "SAMSUNG S3C2442"
select CPU_ARM920T
select S3C2410_COMMON_CLK
- select S3C2410_DMA if S3C24XX_DMA
select S3C2410_PM if PM
help
Support for S3C2442 Samsung Mobile CPU based systems.
@@ -80,7 +75,6 @@ config CPU_S3C2443
bool "SAMSUNG S3C2443"
select CPU_ARM920T
select S3C2443_COMMON_CLK
- select S3C2443_DMA if S3C24XX_DMA
help
Support for the S3C2443 SoC from the S3C24XX line
@@ -114,27 +108,6 @@ config S3C24XX_SETUP_TS
help
Compile in platform device definition for Samsung TouchScreen.
-config S3C24XX_DMA
- bool "S3C2410 DMA support (deprecated)"
- select S3C_DMA
- help
- S3C2410 DMA support. This is needed for drivers like sound which
- use the S3C2410's DMA system to move data to and from the
- peripheral blocks.
-
-config S3C2410_DMA_DEBUG
- bool "S3C2410 DMA support debug"
- depends on S3C2410_DMA
- help
- Enable debugging output for the DMA code. This option sends info
- to the kernel log, at priority KERN_DEBUG.
-
-config S3C2410_DMA
- bool
- depends on S3C24XX_DMA && (CPU_S3C2410 || CPU_S3C2442)
- help
- DMA device selection for S3C2410 and compatible CPUs
-
config S3C2410_PM
bool
help
@@ -325,11 +298,6 @@ config CPU_S3C2412_ONLY
!CPU_S3C2442 && !CPU_S3C2443
default y
-config S3C2412_DMA
- bool
- help
- Internal config node for S3C2412 DMA support
-
config S3C2412_PM
bool
select S3C2412_PM_SLEEP
@@ -438,11 +406,6 @@ endif # CPU_S3C2416
if CPU_S3C2440
-config S3C2440_DMA
- bool
- help
- Support for S3C2440 specific DMA code5A
-
config S3C2440_XTAL_12000000
bool
help
@@ -601,11 +564,6 @@ endif # CPU_S3C2442
if CPU_S3C2443 || CPU_S3C2416
-config S3C2443_DMA
- bool
- help
- Internal config node for S3C2443 DMA support
-
config S3C2443_SETUP_SPI
bool
help
diff --git a/arch/arm/mach-s3c24xx/Makefile b/arch/arm/mach-s3c24xx/Makefile
index b92071638733..b40a22fe082a 100644
--- a/arch/arm/mach-s3c24xx/Makefile
+++ b/arch/arm/mach-s3c24xx/Makefile
@@ -12,12 +12,10 @@
obj-y += common.o
obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
-obj-$(CONFIG_S3C2410_DMA) += dma-s3c2410.o
obj-$(CONFIG_S3C2410_PLL) += pll-s3c2410.o
obj-$(CONFIG_S3C2410_PM) += pm-s3c2410.o sleep-s3c2410.o
obj-$(CONFIG_CPU_S3C2412) += s3c2412.o
-obj-$(CONFIG_S3C2412_DMA) += dma-s3c2412.o
obj-$(CONFIG_S3C2412_PM) += pm-s3c2412.o
obj-$(CONFIG_S3C2412_PM_SLEEP) += sleep-s3c2412.o
@@ -27,7 +25,6 @@ obj-$(CONFIG_S3C2416_PM) += pm-s3c2416.o
obj-$(CONFIG_CPU_S3C2440) += s3c2440.o
obj-$(CONFIG_CPU_S3C2442) += s3c2442.o
obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
-obj-$(CONFIG_S3C2440_DMA) += dma-s3c2440.o
obj-$(CONFIG_S3C2440_PLL_12000000) += pll-s3c2440-12000000.o
obj-$(CONFIG_S3C2440_PLL_16934400) += pll-s3c2440-16934400.o
@@ -39,15 +36,11 @@ obj-$(CONFIG_PM) += pm.o irq-pm.o sleep.o
# common code
-obj-$(CONFIG_S3C24XX_DMA) += dma.o
-
obj-$(CONFIG_S3C2410_CPUFREQ_UTILS) += cpufreq-utils.o
obj-$(CONFIG_S3C2410_IOTIMING) += iotiming-s3c2410.o
obj-$(CONFIG_S3C2412_IOTIMING) += iotiming-s3c2412.o
-obj-$(CONFIG_S3C2443_DMA) += dma-s3c2443.o
-
#
# machine support
# following is ordered alphabetically by option text.
diff --git a/arch/arm/mach-s3c24xx/dma-s3c2410.c b/arch/arm/mach-s3c24xx/dma-s3c2410.c
deleted file mode 100644
index 09aa12da1789..000000000000
--- a/arch/arm/mach-s3c24xx/dma-s3c2410.c
+++ /dev/null
@@ -1,182 +0,0 @@
-/* linux/arch/arm/mach-s3c2410/dma.c
- *
- * Copyright (c) 2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 DMA selection
- *
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/serial_core.h>
-#include <linux/serial_s3c.h>
-
-#include <mach/map.h>
-#include <mach/dma.h>
-
-#include <plat/cpu.h>
-#include <plat/dma-s3c24xx.h>
-
-#include <mach/regs-gpio.h>
-#include <plat/regs-dma.h>
-#include <mach/regs-lcd.h>
-#include <plat/regs-spi.h>
-
-static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
- [DMACH_XD0] = {
- .name = "xdreq0",
- .channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
- },
- [DMACH_XD1] = {
- .name = "xdreq1",
- .channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
- },
- [DMACH_SDI] = {
- .name = "sdi",
- .channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
- .channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
- .channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
- },
- [DMACH_SPI0] = {
- .name = "spi0",
- .channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
- },
- [DMACH_SPI1] = {
- .name = "spi1",
- .channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
- },
- [DMACH_UART0] = {
- .name = "uart0",
- .channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
- },
- [DMACH_UART1] = {
- .name = "uart1",
- .channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
- },
- [DMACH_UART2] = {
- .name = "uart2",
- .channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
- },
- [DMACH_TIMER] = {
- .name = "timer",
- .channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
- .channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
- .channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
- },
- [DMACH_I2S_IN] = {
- .name = "i2s-sdi",
- .channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
- .channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
- },
- [DMACH_I2S_OUT] = {
- .name = "i2s-sdo",
- .channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
- },
- [DMACH_USB_EP1] = {
- .name = "usb-ep1",
- .channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
- },
- [DMACH_USB_EP2] = {
- .name = "usb-ep2",
- .channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
- },
- [DMACH_USB_EP3] = {
- .name = "usb-ep3",
- .channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
- },
- [DMACH_USB_EP4] = {
- .name = "usb-ep4",
- .channels[3] =S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
- },
-};
-
-static void s3c2410_dma_select(struct s3c2410_dma_chan *chan,
- struct s3c24xx_dma_map *map)
-{
- chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
-}
-
-static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = {
- .select = s3c2410_dma_select,
- .dcon_mask = 7 << 24,
- .map = s3c2410_dma_mappings,
- .map_size = ARRAY_SIZE(s3c2410_dma_mappings),
-};
-
-static struct s3c24xx_dma_order __initdata s3c2410_dma_order = {
- .channels = {
- [DMACH_SDI] = {
- .list = {
- [0] = 3 | DMA_CH_VALID,
- [1] = 2 | DMA_CH_VALID,
- [2] = 0 | DMA_CH_VALID,
- },
- },
- [DMACH_I2S_IN] = {
- .list = {
- [0] = 1 | DMA_CH_VALID,
- [1] = 2 | DMA_CH_VALID,
- },
- },
- },
-};
-
-static int __init s3c2410_dma_add(struct device *dev,
- struct subsys_interface *sif)
-{
- s3c2410_dma_init();
- s3c24xx_dma_order_set(&s3c2410_dma_order);
- return s3c24xx_dma_init_map(&s3c2410_dma_sel);
-}
-
-#if defined(CONFIG_CPU_S3C2410)
-static struct subsys_interface s3c2410_dma_interface = {
- .name = "s3c2410_dma",
- .subsys = &s3c2410_subsys,
- .add_dev = s3c2410_dma_add,
-};
-
-static int __init s3c2410_dma_drvinit(void)
-{
- return subsys_interface_register(&s3c2410_dma_interface);
-}
-
-arch_initcall(s3c2410_dma_drvinit);
-
-static struct subsys_interface s3c2410a_dma_interface = {
- .name = "s3c2410a_dma",
- .subsys = &s3c2410a_subsys,
- .add_dev = s3c2410_dma_add,
-};
-
-static int __init s3c2410a_dma_drvinit(void)
-{
- return subsys_interface_register(&s3c2410a_dma_interface);
-}
-
-arch_initcall(s3c2410a_dma_drvinit);
-#endif
-
-#if defined(CONFIG_CPU_S3C2442)
-/* S3C2442 DMA contains the same selection table as the S3C2410 */
-static struct subsys_interface s3c2442_dma_interface = {
- .name = "s3c2442_dma",
- .subsys = &s3c2442_subsys,
- .add_dev = s3c2410_dma_add,
-};
-
-static int __init s3c2442_dma_drvinit(void)
-{
- return subsys_interface_register(&s3c2442_dma_interface);
-}
-
-arch_initcall(s3c2442_dma_drvinit);
-#endif
-
diff --git a/arch/arm/mach-s3c24xx/dma-s3c2412.c b/arch/arm/mach-s3c24xx/dma-s3c2412.c
deleted file mode 100644
index 0c0106d1a4d1..000000000000
--- a/arch/arm/mach-s3c24xx/dma-s3c2412.c
+++ /dev/null
@@ -1,150 +0,0 @@
-/* linux/arch/arm/mach-s3c2412/dma.c
- *
- * Copyright (c) 2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2412 DMA selection
- *
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/serial_core.h>
-#include <linux/serial_s3c.h>
-#include <linux/io.h>
-
-#include <mach/dma.h>
-
-#include <plat/dma-s3c24xx.h>
-#include <plat/cpu.h>
-
-#include <mach/regs-gpio.h>
-#include <plat/regs-dma.h>
-#include <mach/regs-lcd.h>
-#include <plat/regs-spi.h>
-
-#define MAP(x) { (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID, (x)| DMA_CH_VALID }
-
-static struct s3c24xx_dma_map __initdata s3c2412_dma_mappings[] = {
- [DMACH_XD0] = {
- .name = "xdreq0",
- .channels = MAP(S3C2412_DMAREQSEL_XDREQ0),
- },
- [DMACH_XD1] = {
- .name = "xdreq1",
- .channels = MAP(S3C2412_DMAREQSEL_XDREQ1),
- },
- [DMACH_SDI] = {
- .name = "sdi",
- .channels = MAP(S3C2412_DMAREQSEL_SDI),
- },
- [DMACH_SPI0_RX] = {
- .name = "spi0-rx",
- .channels = MAP(S3C2412_DMAREQSEL_SPI0RX),
- },
- [DMACH_SPI0_TX] = {
- .name = "spi0-tx",
- .channels = MAP(S3C2412_DMAREQSEL_SPI0TX),
- },
- [DMACH_SPI1_RX] = {
- .name = "spi1-rx",
- .channels = MAP(S3C2412_DMAREQSEL_SPI1RX),
- },
- [DMACH_SPI1_TX] = {
- .name = "spi1-tx",
- .channels = MAP(S3C2412_DMAREQSEL_SPI1TX),
- },
- [DMACH_UART0] = {
- .name = "uart0",
- .channels = MAP(S3C2412_DMAREQSEL_UART0_0),
- },
- [DMACH_UART1] = {
- .name = "uart1",
- .channels = MAP(S3C2412_DMAREQSEL_UART1_0),
- },
- [DMACH_UART2] = {
- .name = "uart2",
- .channels = MAP(S3C2412_DMAREQSEL_UART2_0),
- },
- [DMACH_UART0_SRC2] = {
- .name = "uart0",
- .channels = MAP(S3C2412_DMAREQSEL_UART0_1),
- },
- [DMACH_UART1_SRC2] = {
- .name = "uart1",
- .channels = MAP(S3C2412_DMAREQSEL_UART1_1),
- },
- [DMACH_UART2_SRC2] = {
- .name = "uart2",
- .channels = MAP(S3C2412_DMAREQSEL_UART2_1),
- },
- [DMACH_TIMER] = {
- .name = "timer",
- .channels = MAP(S3C2412_DMAREQSEL_TIMER),
- },
- [DMACH_I2S_IN] = {
- .name = "i2s-sdi",
- .channels = MAP(S3C2412_DMAREQSEL_I2SRX),
- },
- [DMACH_I2S_OUT] = {
- .name = "i2s-sdo",
- .channels = MAP(S3C2412_DMAREQSEL_I2STX),
- },
- [DMACH_USB_EP1] = {
- .name = "usb-ep1",
- .channels = MAP(S3C2412_DMAREQSEL_USBEP1),
- },
- [DMACH_USB_EP2] = {
- .name = "usb-ep2",
- .channels = MAP(S3C2412_DMAREQSEL_USBEP2),
- },
- [DMACH_USB_EP3] = {
- .name = "usb-ep3",
- .channels = MAP(S3C2412_DMAREQSEL_USBEP3),
- },
- [DMACH_USB_EP4] = {
- .name = "usb-ep4",
- .channels = MAP(S3C2412_DMAREQSEL_USBEP4),
- },
-};
-
-static void s3c2412_dma_select(struct s3c2410_dma_chan *chan,
- struct s3c24xx_dma_map *map)
-{
- unsigned long chsel = map->channels[0] & (~DMA_CH_VALID);
- writel(chsel | S3C2412_DMAREQSEL_HW,
- chan->regs + S3C2412_DMA_DMAREQSEL);
-}
-
-static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = {
- .select = s3c2412_dma_select,
- .dcon_mask = 0,
- .map = s3c2412_dma_mappings,
- .map_size = ARRAY_SIZE(s3c2412_dma_mappings),
-};
-
-static int __init s3c2412_dma_add(struct device *dev,
- struct subsys_interface *sif)
-{
- s3c2410_dma_init();
- return s3c24xx_dma_init_map(&s3c2412_dma_sel);
-}
-
-static struct subsys_interface s3c2412_dma_interface = {
- .name = "s3c2412_dma",
- .subsys = &s3c2412_subsys,
- .add_dev = s3c2412_dma_add,
-};
-
-static int __init s3c2412_dma_init(void)
-{
- return subsys_interface_register(&s3c2412_dma_interface);
-}
-
-arch_initcall(s3c2412_dma_init);
diff --git a/arch/arm/mach-s3c24xx/dma-s3c2440.c b/arch/arm/mach-s3c24xx/dma-s3c2440.c
deleted file mode 100644
index 2f8e8a3017df..000000000000
--- a/arch/arm/mach-s3c24xx/dma-s3c2440.c
+++ /dev/null
@@ -1,193 +0,0 @@
-/* linux/arch/arm/mach-s3c2440/dma.c
- *
- * Copyright (c) 2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2440 DMA selection
- *
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/serial_core.h>
-#include <linux/serial_s3c.h>
-
-#include <mach/map.h>
-#include <mach/dma.h>
-
-#include <plat/dma-s3c24xx.h>
-#include <plat/cpu.h>
-
-#include <mach/regs-gpio.h>
-#include <plat/regs-dma.h>
-#include <mach/regs-lcd.h>
-#include <plat/regs-spi.h>
-
-static struct s3c24xx_dma_map __initdata s3c2440_dma_mappings[] = {
- [DMACH_XD0] = {
- .name = "xdreq0",
- .channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
- },
- [DMACH_XD1] = {
- .name = "xdreq1",
- .channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
- },
- [DMACH_SDI] = {
- .name = "sdi",
- .channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
- .channels[1] = S3C2440_DCON_CH1_SDI | DMA_CH_VALID,
- .channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
- .channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
- },
- [DMACH_SPI0] = {
- .name = "spi0",
- .channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
- },
- [DMACH_SPI1] = {
- .name = "spi1",
- .channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
- },
- [DMACH_UART0] = {
- .name = "uart0",
- .channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
- },
- [DMACH_UART1] = {
- .name = "uart1",
- .channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
- },
- [DMACH_UART2] = {
- .name = "uart2",
- .channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
- },
- [DMACH_TIMER] = {
- .name = "timer",
- .channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
- .channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
- .channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
- },
- [DMACH_I2S_IN] = {
- .name = "i2s-sdi",
- .channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
- .channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
- },
- [DMACH_I2S_OUT] = {
- .name = "i2s-sdo",
- .channels[0] = S3C2440_DCON_CH0_I2SSDO | DMA_CH_VALID,
- .channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
- },
- [DMACH_PCM_IN] = {
- .name = "pcm-in",
- .channels[0] = S3C2440_DCON_CH0_PCMIN | DMA_CH_VALID,
- .channels[2] = S3C2440_DCON_CH2_PCMIN | DMA_CH_VALID,
- },
- [DMACH_PCM_OUT] = {
- .name = "pcm-out",
- .channels[1] = S3C2440_DCON_CH1_PCMOUT | DMA_CH_VALID,
- .channels[3] = S3C2440_DCON_CH3_PCMOUT | DMA_CH_VALID,
- },
- [DMACH_MIC_IN] = {
- .name = "mic-in",
- .channels[2] = S3C2440_DCON_CH2_MICIN | DMA_CH_VALID,
- .channels[3] = S3C2440_DCON_CH3_MICIN | DMA_CH_VALID,
- },
- [DMACH_USB_EP1] = {
- .name = "usb-ep1",
- .channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
- },
- [DMACH_USB_EP2] = {
- .name = "usb-ep2",
- .channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
- },
- [DMACH_USB_EP3] = {
- .name = "usb-ep3",
- .channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
- },
- [DMACH_USB_EP4] = {
- .name = "usb-ep4",
- .channels[3] = S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
- },
-};
-
-static void s3c2440_dma_select(struct s3c2410_dma_chan *chan,
- struct s3c24xx_dma_map *map)
-{
- chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
-}
-
-static struct s3c24xx_dma_selection __initdata s3c2440_dma_sel = {
- .select = s3c2440_dma_select,
- .dcon_mask = 7 << 24,
- .map = s3c2440_dma_mappings,
- .map_size = ARRAY_SIZE(s3c2440_dma_mappings),
-};
-
-static struct s3c24xx_dma_order __initdata s3c2440_dma_order = {
- .channels = {
- [DMACH_SDI] = {
- .list = {
- [0] = 3 | DMA_CH_VALID,
- [1] = 2 | DMA_CH_VALID,
- [2] = 1 | DMA_CH_VALID,
- [3] = 0 | DMA_CH_VALID,
- },
- },
- [DMACH_I2S_IN] = {
- .list = {
- [0] = 1 | DMA_CH_VALID,
- [1] = 2 | DMA_CH_VALID,
- },
- },
- [DMACH_I2S_OUT] = {
- .list = {
- [0] = 2 | DMA_CH_VALID,
- [1] = 1 | DMA_CH_VALID,
- },
- },
- [DMACH_PCM_IN] = {
- .list = {
- [0] = 2 | DMA_CH_VALID,
- [1] = 1 | DMA_CH_VALID,
- },
- },
- [DMACH_PCM_OUT] = {
- .list = {
- [0] = 1 | DMA_CH_VALID,
- [1] = 3 | DMA_CH_VALID,
- },
- },
- [DMACH_MIC_IN] = {
- .list = {
- [0] = 3 | DMA_CH_VALID,
- [1] = 2 | DMA_CH_VALID,
- },
- },
- },
-};
-
-static int __init s3c2440_dma_add(struct device *dev,
- struct subsys_interface *sif)
-{
- s3c2410_dma_init();
- s3c24xx_dma_order_set(&s3c2440_dma_order);
- return s3c24xx_dma_init_map(&s3c2440_dma_sel);
-}
-
-static struct subsys_interface s3c2440_dma_interface = {
- .name = "s3c2440_dma",
- .subsys = &s3c2440_subsys,
- .add_dev = s3c2440_dma_add,
-};
-
-static int __init s3c2440_dma_init(void)
-{
- return subsys_interface_register(&s3c2440_dma_interface);
-}
-
-arch_initcall(s3c2440_dma_init);
-
diff --git a/arch/arm/mach-s3c24xx/dma-s3c2443.c b/arch/arm/mach-s3c24xx/dma-s3c2443.c
deleted file mode 100644
index f4096ec0700a..000000000000
--- a/arch/arm/mach-s3c24xx/dma-s3c2443.c
+++ /dev/null
@@ -1,179 +0,0 @@
-/* linux/arch/arm/mach-s3c2443/dma.c
- *
- * Copyright (c) 2007 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2443 DMA selection
- *
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/device.h>
-#include <linux/serial_core.h>
-#include <linux/serial_s3c.h>
-#include <linux/io.h>
-
-#include <mach/dma.h>
-
-#include <plat/dma-s3c24xx.h>
-#include <plat/cpu.h>
-
-#include <mach/regs-gpio.h>
-#include <plat/regs-dma.h>
-#include <mach/regs-lcd.h>
-#include <plat/regs-spi.h>
-
-#define MAP(x) { \
- [0] = (x) | DMA_CH_VALID, \
- [1] = (x) | DMA_CH_VALID, \
- [2] = (x) | DMA_CH_VALID, \
- [3] = (x) | DMA_CH_VALID, \
- [4] = (x) | DMA_CH_VALID, \
- [5] = (x) | DMA_CH_VALID, \
- }
-
-static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = {
- [DMACH_XD0] = {
- .name = "xdreq0",
- .channels = MAP(S3C2443_DMAREQSEL_XDREQ0),
- },
- [DMACH_XD1] = {
- .name = "xdreq1",
- .channels = MAP(S3C2443_DMAREQSEL_XDREQ1),
- },
- [DMACH_SDI] = { /* only on S3C2443 */
- .name = "sdi",
- .channels = MAP(S3C2443_DMAREQSEL_SDI),
- },
- [DMACH_SPI0_RX] = {
- .name = "spi0-rx",
- .channels = MAP(S3C2443_DMAREQSEL_SPI0RX),
- },
- [DMACH_SPI0_TX] = {
- .name = "spi0-tx",
- .channels = MAP(S3C2443_DMAREQSEL_SPI0TX),
- },
- [DMACH_SPI1_RX] = { /* only on S3C2443/S3C2450 */
- .name = "spi1-rx",
- .channels = MAP(S3C2443_DMAREQSEL_SPI1RX),
- },
- [DMACH_SPI1_TX] = { /* only on S3C2443/S3C2450 */
- .name = "spi1-tx",
- .channels = MAP(S3C2443_DMAREQSEL_SPI1TX),
- },
- [DMACH_UART0] = {
- .name = "uart0",
- .channels = MAP(S3C2443_DMAREQSEL_UART0_0),
- },
- [DMACH_UART1] = {
- .name = "uart1",
- .channels = MAP(S3C2443_DMAREQSEL_UART1_0),
- },
- [DMACH_UART2] = {
- .name = "uart2",
- .channels = MAP(S3C2443_DMAREQSEL_UART2_0),
- },
- [DMACH_UART3] = {
- .name = "uart3",
- .channels = MAP(S3C2443_DMAREQSEL_UART3_0),
- },
- [DMACH_UART0_SRC2] = {
- .name = "uart0",
- .channels = MAP(S3C2443_DMAREQSEL_UART0_1),
- },
- [DMACH_UART1_SRC2] = {
- .name = "uart1",
- .channels = MAP(S3C2443_DMAREQSEL_UART1_1),
- },
- [DMACH_UART2_SRC2] = {
- .name = "uart2",
- .channels = MAP(S3C2443_DMAREQSEL_UART2_1),
- },
- [DMACH_UART3_SRC2] = {
- .name = "uart3",
- .channels = MAP(S3C2443_DMAREQSEL_UART3_1),
- },
- [DMACH_TIMER] = {
- .name = "timer",
- .channels = MAP(S3C2443_DMAREQSEL_TIMER),
- },
- [DMACH_I2S_IN] = {
- .name = "i2s-sdi",
- .channels = MAP(S3C2443_DMAREQSEL_I2SRX),
- },
- [DMACH_I2S_OUT] = {
- .name = "i2s-sdo",
- .channels = MAP(S3C2443_DMAREQSEL_I2STX),
- },
- [DMACH_PCM_IN] = {
- .name = "pcm-in",
- .channels = MAP(S3C2443_DMAREQSEL_PCMIN),
- },
- [DMACH_PCM_OUT] = {
- .name = "pcm-out",
- .channels = MAP(S3C2443_DMAREQSEL_PCMOUT),
- },
- [DMACH_MIC_IN] = {
- .name = "mic-in",
- .channels = MAP(S3C2443_DMAREQSEL_MICIN),
- },
-};
-
-static void s3c2443_dma_select(struct s3c2410_dma_chan *chan,
- struct s3c24xx_dma_map *map)
-{
- unsigned long chsel = map->channels[0] & (~DMA_CH_VALID);
- writel(chsel | S3C2443_DMAREQSEL_HW,
- chan->regs + S3C2443_DMA_DMAREQSEL);
-}
-
-static struct s3c24xx_dma_selection __initdata s3c2443_dma_sel = {
- .select = s3c2443_dma_select,
- .dcon_mask = 0,
- .map = s3c2443_dma_mappings,
- .map_size = ARRAY_SIZE(s3c2443_dma_mappings),
-};
-
-static int __init s3c2443_dma_add(struct device *dev,
- struct subsys_interface *sif)
-{
- s3c24xx_dma_init(6, IRQ_S3C2443_DMA0, 0x100);
- return s3c24xx_dma_init_map(&s3c2443_dma_sel);
-}
-
-#ifdef CONFIG_CPU_S3C2416
-/* S3C2416 DMA contains the same selection table as the S3C2443 */
-static struct subsys_interface s3c2416_dma_interface = {
- .name = "s3c2416_dma",
- .subsys = &s3c2416_subsys,
- .add_dev = s3c2443_dma_add,
-};
-
-static int __init s3c2416_dma_init(void)
-{
- return subsys_interface_register(&s3c2416_dma_interface);
-}
-
-arch_initcall(s3c2416_dma_init);
-#endif
-
-#ifdef CONFIG_CPU_S3C2443
-static struct subsys_interface s3c2443_dma_interface = {
- .name = "s3c2443_dma",
- .subsys = &s3c2443_subsys,
- .add_dev = s3c2443_dma_add,
-};
-
-static int __init s3c2443_dma_init(void)
-{
- return subsys_interface_register(&s3c2443_dma_interface);
-}
-
-arch_initcall(s3c2443_dma_init);
-#endif
diff --git a/arch/arm/mach-s3c24xx/dma.c b/arch/arm/mach-s3c24xx/dma.c
deleted file mode 100644
index a8dafc174fe3..000000000000
--- a/arch/arm/mach-s3c24xx/dma.c
+++ /dev/null
@@ -1,1465 +0,0 @@
-/*
- * Copyright 2003-2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * S3C2410 DMA core
- *
- * http://armlinux.simtec.co.uk/
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-
-#ifdef CONFIG_S3C2410_DMA_DEBUG
-#define DEBUG
-#endif
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <linux/interrupt.h>
-#include <linux/syscore_ops.h>
-#include <linux/slab.h>
-#include <linux/errno.h>
-#include <linux/io.h>
-
-#include <asm/irq.h>
-#include <mach/hardware.h>
-#include <mach/dma.h>
-#include <mach/map.h>
-
-#include <plat/dma-s3c24xx.h>
-#include <plat/regs-dma.h>
-
-/* io map for dma */
-static void __iomem *dma_base;
-static struct kmem_cache *dma_kmem;
-
-static int dma_channels;
-
-static struct s3c24xx_dma_selection dma_sel;
-
-
-/* debugging functions */
-
-#define BUF_MAGIC (0xcafebabe)
-
-#define dmawarn(fmt...) printk(KERN_DEBUG fmt)
-
-#define dma_regaddr(chan, reg) ((chan)->regs + (reg))
-
-#if 1
-#define dma_wrreg(chan, reg, val) writel((val), (chan)->regs + (reg))
-#else
-static inline void
-dma_wrreg(struct s3c2410_dma_chan *chan, int reg, unsigned long val)
-{
- pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg);
- writel(val, dma_regaddr(chan, reg));
-}
-#endif
-
-#define dma_rdreg(chan, reg) readl((chan)->regs + (reg))
-
-/* captured register state for debug */
-
-struct s3c2410_dma_regstate {
- unsigned long dcsrc;
- unsigned long disrc;
- unsigned long dstat;
- unsigned long dcon;
- unsigned long dmsktrig;
-};
-
-#ifdef CONFIG_S3C2410_DMA_DEBUG
-
-/* dmadbg_showregs
- *
- * simple debug routine to print the current state of the dma registers
-*/
-
-static void
-dmadbg_capture(struct s3c2410_dma_chan *chan, struct s3c2410_dma_regstate *regs)
-{
- regs->dcsrc = dma_rdreg(chan, S3C2410_DMA_DCSRC);
- regs->disrc = dma_rdreg(chan, S3C2410_DMA_DISRC);
- regs->dstat = dma_rdreg(chan, S3C2410_DMA_DSTAT);
- regs->dcon = dma_rdreg(chan, S3C2410_DMA_DCON);
- regs->dmsktrig = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
-}
-
-static void
-dmadbg_dumpregs(const char *fname, int line, struct s3c2410_dma_chan *chan,
- struct s3c2410_dma_regstate *regs)
-{
- printk(KERN_DEBUG "dma%d: %s:%d: DCSRC=%08lx, DISRC=%08lx, DSTAT=%08lx DMT=%02lx, DCON=%08lx\n",
- chan->number, fname, line,
- regs->dcsrc, regs->disrc, regs->dstat, regs->dmsktrig,
- regs->dcon);
-}
-
-static void
-dmadbg_showchan(const char *fname, int line, struct s3c2410_dma_chan *chan)
-{
- struct s3c2410_dma_regstate state;
-
- dmadbg_capture(chan, &state);
-
- printk(KERN_DEBUG "dma%d: %s:%d: ls=%d, cur=%p, %p %p\n",
- chan->number, fname, line, chan->load_state,
- chan->curr, chan->next, chan->end);
-
- dmadbg_dumpregs(fname, line, chan, &state);
-}
-
-static void
-dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan)
-{
- struct s3c2410_dma_regstate state;
-
- dmadbg_capture(chan, &state);
- dmadbg_dumpregs(fname, line, chan, &state);
-}
-
-#define dbg_showregs(chan) dmadbg_showregs(__func__, __LINE__, (chan))
-#define dbg_showchan(chan) dmadbg_showchan(__func__, __LINE__, (chan))
-#else
-#define dbg_showregs(chan) do { } while(0)
-#define dbg_showchan(chan) do { } while(0)
-#endif /* CONFIG_S3C2410_DMA_DEBUG */
-
-/* s3c2410_dma_stats_timeout
- *
- * Update DMA stats from timeout info
-*/
-
-static void
-s3c2410_dma_stats_timeout(struct s3c2410_dma_stats *stats, int val)
-{
- if (stats == NULL)
- return;
-
- if (val > stats->timeout_longest)
- stats->timeout_longest = val;
- if (val < stats->timeout_shortest)
- stats->timeout_shortest = val;
-
- stats->timeout_avg += val;
-}
-
-/* s3c2410_dma_waitforload
- *
- * wait for the DMA engine to load a buffer, and update the state accordingly
-*/
-
-static int
-s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line)
-{
- int timeout = chan->load_timeout;
- int took;
-
- if (chan->load_state != S3C2410_DMALOAD_1LOADED) {
- printk(KERN_ERR "dma%d: s3c2410_dma_waitforload() called in loadstate %d from line %d\n", chan->number, chan->load_state, line);
- return 0;
- }
-
- if (chan->stats != NULL)
- chan->stats->loads++;
-
- while (--timeout > 0) {
- if ((dma_rdreg(chan, S3C2410_DMA_DSTAT) << (32-20)) != 0) {
- took = chan->load_timeout - timeout;
-
- s3c2410_dma_stats_timeout(chan->stats, took);
-
- switch (chan->load_state) {
- case S3C2410_DMALOAD_1LOADED:
- chan->load_state = S3C2410_DMALOAD_1RUNNING;
- break;
-
- default:
- printk(KERN_ERR "dma%d: unknown load_state in s3c2410_dma_waitforload() %d\n", chan->number, chan->load_state);
- }
-
- return 1;
- }
- }
-
- if (chan->stats != NULL) {
- chan->stats->timeout_failed++;
- }
-
- return 0;
-}
-
-/* s3c2410_dma_loadbuffer
- *
- * load a buffer, and update the channel state
-*/
-
-static inline int
-s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan,
- struct s3c2410_dma_buf *buf)
-{
- unsigned long reload;
-
- if (buf == NULL) {
- dmawarn("buffer is NULL\n");
- return -EINVAL;
- }
-
- pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n",
- buf, (unsigned long)buf->data, buf->size);
-
- /* check the state of the channel before we do anything */
-
- if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
- dmawarn("load_state is S3C2410_DMALOAD_1LOADED\n");
- }
-
- if (chan->load_state == S3C2410_DMALOAD_1LOADED_1RUNNING) {
- dmawarn("state is S3C2410_DMALOAD_1LOADED_1RUNNING\n");
- }
-
- /* it would seem sensible if we are the last buffer to not bother
- * with the auto-reload bit, so that the DMA engine will not try
- * and load another transfer after this one has finished...
- */
- if (chan->load_state == S3C2410_DMALOAD_NONE) {
- pr_debug("load_state is none, checking for noreload (next=%p)\n",
- buf->next);
- reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0;
- } else {
- //pr_debug("load_state is %d => autoreload\n", chan->load_state);
- reload = S3C2410_DCON_AUTORELOAD;
- }
-
- if ((buf->data & 0xf0000000) != 0x30000000) {
- dmawarn("dmaload: buffer is %p\n", (void *)buf->data);
- }
-
- writel(buf->data, chan->addr_reg);
-
- dma_wrreg(chan, S3C2410_DMA_DCON,
- chan->dcon | reload | (buf->size/chan->xfer_unit));
-
- chan->next = buf->next;
-
- /* update the state of the channel */
-
- switch (chan->load_state) {
- case S3C2410_DMALOAD_NONE:
- chan->load_state = S3C2410_DMALOAD_1LOADED;
- break;
-
- case S3C2410_DMALOAD_1RUNNING:
- chan->load_state = S3C2410_DMALOAD_1LOADED_1RUNNING;
- break;
-
- default:
- dmawarn("dmaload: unknown state %d in loadbuffer\n",
- chan->load_state);
- break;
- }
-
- return 0;
-}
-
-/* s3c2410_dma_call_op
- *
- * small routine to call the op routine with the given op if it has been
- * registered
-*/
-
-static void
-s3c2410_dma_call_op(struct s3c2410_dma_chan *chan, enum s3c2410_chan_op op)
-{
- if (chan->op_fn != NULL) {
- (chan->op_fn)(chan, op);
- }
-}
-
-/* s3c2410_dma_buffdone
- *
- * small wrapper to check if callback routine needs to be called, and
- * if so, call it
-*/
-
-static inline void
-s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf,
- enum s3c2410_dma_buffresult result)
-{
-#if 0
- pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n",
- chan->callback_fn, buf, buf->id, buf->size, result);
-#endif
-
- if (chan->callback_fn != NULL) {
- (chan->callback_fn)(chan, buf->id, buf->size, result);
- }
-}
-
-/* s3c2410_dma_start
- *
- * start a dma channel going
-*/
-
-static int s3c2410_dma_start(struct s3c2410_dma_chan *chan)
-{
- unsigned long tmp;
- unsigned long flags;
-
- pr_debug("s3c2410_start_dma: channel=%d\n", chan->number);
-
- local_irq_save(flags);
-
- if (chan->state == S3C2410_DMA_RUNNING) {
- pr_debug("s3c2410_start_dma: already running (%d)\n", chan->state);
- local_irq_restore(flags);
- return 0;
- }
-
- chan->state = S3C2410_DMA_RUNNING;
-
- /* check whether there is anything to load, and if not, see
- * if we can find anything to load
- */
-
- if (chan->load_state == S3C2410_DMALOAD_NONE) {
- if (chan->next == NULL) {
- printk(KERN_ERR "dma%d: channel has nothing loaded\n",
- chan->number);
- chan->state = S3C2410_DMA_IDLE;
- local_irq_restore(flags);
- return -EINVAL;
- }
-
- s3c2410_dma_loadbuffer(chan, chan->next);
- }
-
- dbg_showchan(chan);
-
- /* enable the channel */
-
- if (!chan->irq_enabled) {
- enable_irq(chan->irq);
- chan->irq_enabled = 1;
- }
-
- /* start the channel going */
-
- tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
- tmp &= ~S3C2410_DMASKTRIG_STOP;
- tmp |= S3C2410_DMASKTRIG_ON;
- dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
-
- pr_debug("dma%d: %08lx to DMASKTRIG\n", chan->number, tmp);
-
-#if 0
- /* the dma buffer loads should take care of clearing the AUTO
- * reloading feature */
- tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
- tmp &= ~S3C2410_DCON_NORELOAD;
- dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
-#endif
-
- s3c2410_dma_call_op(chan, S3C2410_DMAOP_START);
-
- dbg_showchan(chan);
-
- /* if we've only loaded one buffer onto the channel, then chec
- * to see if we have another, and if so, try and load it so when
- * the first buffer is finished, the new one will be loaded onto
- * the channel */
-
- if (chan->next != NULL) {
- if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
-
- if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
- pr_debug("%s: buff not yet loaded, no more todo\n",
- __func__);
- } else {
- chan->load_state = S3C2410_DMALOAD_1RUNNING;
- s3c2410_dma_loadbuffer(chan, chan->next);
- }
-
- } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
- s3c2410_dma_loadbuffer(chan, chan->next);
- }
- }
-
-
- local_irq_restore(flags);
-
- return 0;
-}
-
-/* s3c2410_dma_canload
- *
- * work out if we can queue another buffer into the DMA engine
-*/
-
-static int
-s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
-{
- if (chan->load_state == S3C2410_DMALOAD_NONE ||
- chan->load_state == S3C2410_DMALOAD_1RUNNING)
- return 1;
-
- return 0;
-}
-
-/* s3c2410_dma_enqueue
- *
- * queue an given buffer for dma transfer.
- *
- * id the device driver's id information for this buffer
- * data the physical address of the buffer data
- * size the size of the buffer in bytes
- *
- * If the channel is not running, then the flag S3C2410_DMAF_AUTOSTART
- * is checked, and if set, the channel is started. If this flag isn't set,
- * then an error will be returned.
- *
- * It is possible to queue more than one DMA buffer onto a channel at
- * once, and the code will deal with the re-loading of the next buffer
- * when necessary.
-*/
-
-int s3c2410_dma_enqueue(enum dma_ch channel, void *id,
- dma_addr_t data, int size)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
- struct s3c2410_dma_buf *buf;
- unsigned long flags;
-
- if (chan == NULL)
- return -EINVAL;
-
- pr_debug("%s: id=%p, data=%08x, size=%d\n",
- __func__, id, (unsigned int)data, size);
-
- buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);
- if (buf == NULL) {
- pr_debug("%s: out of memory (%ld alloc)\n",
- __func__, (long)sizeof(*buf));
- return -ENOMEM;
- }
-
- //pr_debug("%s: new buffer %p\n", __func__, buf);
- //dbg_showchan(chan);
-
- buf->next = NULL;
- buf->data = buf->ptr = data;
- buf->size = size;
- buf->id = id;
- buf->magic = BUF_MAGIC;
-
- local_irq_save(flags);
-
- if (chan->curr == NULL) {
- /* we've got nothing loaded... */
- pr_debug("%s: buffer %p queued onto empty channel\n",
- __func__, buf);
-
- chan->curr = buf;
- chan->end = buf;
- chan->next = NULL;
- } else {
- pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n",
- chan->number, __func__, buf);
-
- if (chan->end == NULL) {
- pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n",
- chan->number, __func__, chan);
- } else {
- chan->end->next = buf;
- chan->end = buf;
- }
- }
-
- /* if necessary, update the next buffer field */
- if (chan->next == NULL)
- chan->next = buf;
-
- /* check to see if we can load a buffer */
- if (chan->state == S3C2410_DMA_RUNNING) {
- if (chan->load_state == S3C2410_DMALOAD_1LOADED && 1) {
- if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
- printk(KERN_ERR "dma%d: loadbuffer:"
- "timeout loading buffer\n",
- chan->number);
- dbg_showchan(chan);
- local_irq_restore(flags);
- return -EINVAL;
- }
- }
-
- while (s3c2410_dma_canload(chan) && chan->next != NULL) {
- s3c2410_dma_loadbuffer(chan, chan->next);
- }
- } else if (chan->state == S3C2410_DMA_IDLE) {
- if (chan->flags & S3C2410_DMAF_AUTOSTART) {
- s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,
- S3C2410_DMAOP_START);
- }
- }
-
- local_irq_restore(flags);
- return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_enqueue);
-
-static inline void
-s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf)
-{
- int magicok = (buf->magic == BUF_MAGIC);
-
- buf->magic = -1;
-
- if (magicok) {
- kmem_cache_free(dma_kmem, buf);
- } else {
- printk("s3c2410_dma_freebuf: buff %p with bad magic\n", buf);
- }
-}
-
-/* s3c2410_dma_lastxfer
- *
- * called when the system is out of buffers, to ensure that the channel
- * is prepared for shutdown.
-*/
-
-static inline void
-s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan)
-{
-#if 0
- pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n",
- chan->number, chan->load_state);
-#endif
-
- switch (chan->load_state) {
- case S3C2410_DMALOAD_NONE:
- break;
-
- case S3C2410_DMALOAD_1LOADED:
- if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
- /* flag error? */
- printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
- chan->number, __func__);
- return;
- }
- break;
-
- case S3C2410_DMALOAD_1LOADED_1RUNNING:
- /* I believe in this case we do not have anything to do
- * until the next buffer comes along, and we turn off the
- * reload */
- return;
-
- default:
- pr_debug("dma%d: lastxfer: unhandled load_state %d with no next\n",
- chan->number, chan->load_state);
- return;
-
- }
-
- /* hopefully this'll shut the damned thing up after the transfer... */
- dma_wrreg(chan, S3C2410_DMA_DCON, chan->dcon | S3C2410_DCON_NORELOAD);
-}
-
-
-#define dmadbg2(x...)
-
-static irqreturn_t
-s3c2410_dma_irq(int irq, void *devpw)
-{
- struct s3c2410_dma_chan *chan = (struct s3c2410_dma_chan *)devpw;
- struct s3c2410_dma_buf *buf;
-
- buf = chan->curr;
-
- dbg_showchan(chan);
-
- /* modify the channel state */
-
- switch (chan->load_state) {
- case S3C2410_DMALOAD_1RUNNING:
- /* TODO - if we are running only one buffer, we probably
- * want to reload here, and then worry about the buffer
- * callback */
-
- chan->load_state = S3C2410_DMALOAD_NONE;
- break;
-
- case S3C2410_DMALOAD_1LOADED:
- /* iirc, we should go back to NONE loaded here, we
- * had a buffer, and it was never verified as being
- * loaded.
- */
-
- chan->load_state = S3C2410_DMALOAD_NONE;
- break;
-
- case S3C2410_DMALOAD_1LOADED_1RUNNING:
- /* we'll worry about checking to see if another buffer is
- * ready after we've called back the owner. This should
- * ensure we do not wait around too long for the DMA
- * engine to start the next transfer
- */
-
- chan->load_state = S3C2410_DMALOAD_1LOADED;
- break;
-
- case S3C2410_DMALOAD_NONE:
- printk(KERN_ERR "dma%d: IRQ with no loaded buffer?\n",
- chan->number);
- break;
-
- default:
- printk(KERN_ERR "dma%d: IRQ in invalid load_state %d\n",
- chan->number, chan->load_state);
- break;
- }
-
- if (buf != NULL) {
- /* update the chain to make sure that if we load any more
- * buffers when we call the callback function, things should
- * work properly */
-
- chan->curr = buf->next;
- buf->next = NULL;
-
- if (buf->magic != BUF_MAGIC) {
- printk(KERN_ERR "dma%d: %s: buf %p incorrect magic\n",
- chan->number, __func__, buf);
- return IRQ_HANDLED;
- }
-
- s3c2410_dma_buffdone(chan, buf, S3C2410_RES_OK);
-
- /* free resouces */
- s3c2410_dma_freebuf(buf);
- } else {
- }
-
- /* only reload if the channel is still running... our buffer done
- * routine may have altered the state by requesting the dma channel
- * to stop or shutdown... */
-
- /* todo: check that when the channel is shut-down from inside this
- * function, we cope with unsetting reload, etc */
-
- if (chan->next != NULL && chan->state != S3C2410_DMA_IDLE) {
- unsigned long flags;
-
- switch (chan->load_state) {
- case S3C2410_DMALOAD_1RUNNING:
- /* don't need to do anything for this state */
- break;
-
- case S3C2410_DMALOAD_NONE:
- /* can load buffer immediately */
- break;
-
- case S3C2410_DMALOAD_1LOADED:
- if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
- /* flag error? */
- printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
- chan->number, __func__);
- return IRQ_HANDLED;
- }
-
- break;
-
- case S3C2410_DMALOAD_1LOADED_1RUNNING:
- goto no_load;
-
- default:
- printk(KERN_ERR "dma%d: unknown load_state in irq, %d\n",
- chan->number, chan->load_state);
- return IRQ_HANDLED;
- }
-
- local_irq_save(flags);
- s3c2410_dma_loadbuffer(chan, chan->next);
- local_irq_restore(flags);
- } else {
- s3c2410_dma_lastxfer(chan);
-
- /* see if we can stop this channel.. */
- if (chan->load_state == S3C2410_DMALOAD_NONE) {
- pr_debug("dma%d: end of transfer, stopping channel (%ld)\n",
- chan->number, jiffies);
- s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,
- S3C2410_DMAOP_STOP);
- }
- }
-
- no_load:
- return IRQ_HANDLED;
-}
-
-static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel);
-
-/* s3c2410_request_dma
- *
- * get control of an dma channel
-*/
-
-int s3c2410_dma_request(enum dma_ch channel,
- struct s3c2410_dma_client *client,
- void *dev)
-{
- struct s3c2410_dma_chan *chan;
- unsigned long flags;
- int err;
-
- pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
- channel, client->name, dev);
-
- local_irq_save(flags);
-
- chan = s3c2410_dma_map_channel(channel);
- if (chan == NULL) {
- local_irq_restore(flags);
- return -EBUSY;
- }
-
- dbg_showchan(chan);
-
- chan->client = client;
- chan->in_use = 1;
-
- if (!chan->irq_claimed) {
- pr_debug("dma%d: %s : requesting irq %d\n",
- channel, __func__, chan->irq);
-
- chan->irq_claimed = 1;
- local_irq_restore(flags);
-
- err = request_irq(chan->irq, s3c2410_dma_irq, 0,
- client->name, (void *)chan);
-
- local_irq_save(flags);
-
- if (err) {
- chan->in_use = 0;
- chan->irq_claimed = 0;
- local_irq_restore(flags);
-
- printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n",
- client->name, chan->irq, chan->number);
- return err;
- }
-
- chan->irq_enabled = 1;
- }
-
- local_irq_restore(flags);
-
- /* need to setup */
-
- pr_debug("%s: channel initialised, %p\n", __func__, chan);
-
- return chan->number | DMACH_LOW_LEVEL;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_request);
-
-/* s3c2410_dma_free
- *
- * release the given channel back to the system, will stop and flush
- * any outstanding transfers, and ensure the channel is ready for the
- * next claimant.
- *
- * Note, although a warning is currently printed if the freeing client
- * info is not the same as the registrant's client info, the free is still
- * allowed to go through.
-*/
-
-int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *client)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
- unsigned long flags;
-
- if (chan == NULL)
- return -EINVAL;
-
- local_irq_save(flags);
-
- if (chan->client != client) {
- printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
- channel, chan->client, client);
- }
-
- /* sort out stopping and freeing the channel */
-
- if (chan->state != S3C2410_DMA_IDLE) {
- pr_debug("%s: need to stop dma channel %p\n",
- __func__, chan);
-
- /* possibly flush the channel */
- s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STOP);
- }
-
- chan->client = NULL;
- chan->in_use = 0;
-
- if (chan->irq_claimed)
- free_irq(chan->irq, (void *)chan);
-
- chan->irq_claimed = 0;
-
- if (!(channel & DMACH_LOW_LEVEL))
- s3c_dma_chan_map[channel] = NULL;
-
- local_irq_restore(flags);
-
- return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_free);
-
-static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan)
-{
- unsigned long flags;
- unsigned long tmp;
-
- pr_debug("%s:\n", __func__);
-
- dbg_showchan(chan);
-
- local_irq_save(flags);
-
- s3c2410_dma_call_op(chan, S3C2410_DMAOP_STOP);
-
- tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
- tmp |= S3C2410_DMASKTRIG_STOP;
- //tmp &= ~S3C2410_DMASKTRIG_ON;
- dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
-
-#if 0
- /* should also clear interrupts, according to WinCE BSP */
- tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
- tmp |= S3C2410_DCON_NORELOAD;
- dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
-#endif
-
- /* should stop do this, or should we wait for flush? */
- chan->state = S3C2410_DMA_IDLE;
- chan->load_state = S3C2410_DMALOAD_NONE;
-
- local_irq_restore(flags);
-
- return 0;
-}
-
-static void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan)
-{
- unsigned long tmp;
- unsigned int timeout = 0x10000;
-
- while (timeout-- > 0) {
- tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
-
- if (!(tmp & S3C2410_DMASKTRIG_ON))
- return;
- }
-
- pr_debug("dma%d: failed to stop?\n", chan->number);
-}
-
-
-/* s3c2410_dma_flush
- *
- * stop the channel, and remove all current and pending transfers
-*/
-
-static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan)
-{
- struct s3c2410_dma_buf *buf, *next;
- unsigned long flags;
-
- pr_debug("%s: chan %p (%d)\n", __func__, chan, chan->number);
-
- dbg_showchan(chan);
-
- local_irq_save(flags);
-
- if (chan->state != S3C2410_DMA_IDLE) {
- pr_debug("%s: stopping channel...\n", __func__ );
- s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP);
- }
-
- buf = chan->curr;
- if (buf == NULL)
- buf = chan->next;
-
- chan->curr = chan->next = chan->end = NULL;
-
- if (buf != NULL) {
- for ( ; buf != NULL; buf = next) {
- next = buf->next;
-
- pr_debug("%s: free buffer %p, next %p\n",
- __func__, buf, buf->next);
-
- s3c2410_dma_buffdone(chan, buf, S3C2410_RES_ABORT);
- s3c2410_dma_freebuf(buf);
- }
- }
-
- dbg_showregs(chan);
-
- s3c2410_dma_waitforstop(chan);
-
-#if 0
- /* should also clear interrupts, according to WinCE BSP */
- {
- unsigned long tmp;
-
- tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
- tmp |= S3C2410_DCON_NORELOAD;
- dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
- }
-#endif
-
- dbg_showregs(chan);
-
- local_irq_restore(flags);
-
- return 0;
-}
-
-static int s3c2410_dma_started(struct s3c2410_dma_chan *chan)
-{
- unsigned long flags;
-
- local_irq_save(flags);
-
- dbg_showchan(chan);
-
- /* if we've only loaded one buffer onto the channel, then chec
- * to see if we have another, and if so, try and load it so when
- * the first buffer is finished, the new one will be loaded onto
- * the channel */
-
- if (chan->next != NULL) {
- if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
-
- if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
- pr_debug("%s: buff not yet loaded, no more todo\n",
- __func__);
- } else {
- chan->load_state = S3C2410_DMALOAD_1RUNNING;
- s3c2410_dma_loadbuffer(chan, chan->next);
- }
-
- } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
- s3c2410_dma_loadbuffer(chan, chan->next);
- }
- }
-
-
- local_irq_restore(flags);
-
- return 0;
-
-}
-
-int
-s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
- if (chan == NULL)
- return -EINVAL;
-
- switch (op) {
- case S3C2410_DMAOP_START:
- return s3c2410_dma_start(chan);
-
- case S3C2410_DMAOP_STOP:
- return s3c2410_dma_dostop(chan);
-
- case S3C2410_DMAOP_PAUSE:
- case S3C2410_DMAOP_RESUME:
- return -ENOENT;
-
- case S3C2410_DMAOP_FLUSH:
- return s3c2410_dma_flush(chan);
-
- case S3C2410_DMAOP_STARTED:
- return s3c2410_dma_started(chan);
-
- case S3C2410_DMAOP_TIMEOUT:
- return 0;
-
- }
-
- return -ENOENT; /* unknown, don't bother */
-}
-
-EXPORT_SYMBOL(s3c2410_dma_ctrl);
-
-/* DMA configuration for each channel
- *
- * DISRCC -> source of the DMA (AHB,APB)
- * DISRC -> source address of the DMA
- * DIDSTC -> destination of the DMA (AHB,APD)
- * DIDST -> destination address of the DMA
-*/
-
-/* s3c2410_dma_config
- *
- * xfersize: size of unit in bytes (1,2,4)
-*/
-
-int s3c2410_dma_config(enum dma_ch channel,
- int xferunit)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
- unsigned int dcon;
-
- pr_debug("%s: chan=%d, xfer_unit=%d\n", __func__, channel, xferunit);
-
- if (chan == NULL)
- return -EINVAL;
-
- dcon = chan->dcon & dma_sel.dcon_mask;
- pr_debug("%s: dcon is %08x\n", __func__, dcon);
-
- switch (chan->req_ch) {
- case DMACH_I2S_IN:
- case DMACH_I2S_OUT:
- case DMACH_PCM_IN:
- case DMACH_PCM_OUT:
- case DMACH_MIC_IN:
- default:
- dcon |= S3C2410_DCON_HANDSHAKE;
- dcon |= S3C2410_DCON_SYNC_PCLK;
- break;
-
- case DMACH_SDI:
- /* note, ensure if need HANDSHAKE or not */
- dcon |= S3C2410_DCON_SYNC_PCLK;
- break;
-
- case DMACH_XD0:
- case DMACH_XD1:
- dcon |= S3C2410_DCON_HANDSHAKE;
- dcon |= S3C2410_DCON_SYNC_HCLK;
- break;
- }
-
- switch (xferunit) {
- case 1:
- dcon |= S3C2410_DCON_BYTE;
- break;
-
- case 2:
- dcon |= S3C2410_DCON_HALFWORD;
- break;
-
- case 4:
- dcon |= S3C2410_DCON_WORD;
- break;
-
- default:
- pr_debug("%s: bad transfer size %d\n", __func__, xferunit);
- return -EINVAL;
- }
-
- dcon |= S3C2410_DCON_HWTRIG;
- dcon |= S3C2410_DCON_INTREQ;
-
- pr_debug("%s: dcon now %08x\n", __func__, dcon);
-
- chan->dcon = dcon;
- chan->xfer_unit = xferunit;
-
- return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_config);
-
-
-/* s3c2410_dma_devconfig
- *
- * configure the dma source/destination hardware type and address
- *
- * source: DMA_FROM_DEVICE: source is hardware
- * DMA_TO_DEVICE: source is memory
- *
- * devaddr: physical address of the source
-*/
-
-int s3c2410_dma_devconfig(enum dma_ch channel,
- enum dma_data_direction source,
- unsigned long devaddr)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
- unsigned int hwcfg;
-
- if (chan == NULL)
- return -EINVAL;
-
- pr_debug("%s: source=%d, devaddr=%08lx\n",
- __func__, (int)source, devaddr);
-
- chan->source = source;
- chan->dev_addr = devaddr;
-
- switch (chan->req_ch) {
- case DMACH_XD0:
- case DMACH_XD1:
- hwcfg = 0; /* AHB */
- break;
-
- default:
- hwcfg = S3C2410_DISRCC_APB;
- }
-
- /* always assume our peripheral desintation is a fixed
- * address in memory. */
- hwcfg |= S3C2410_DISRCC_INC;
-
- switch (source) {
- case DMA_FROM_DEVICE:
- /* source is hardware */
- pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n",
- __func__, devaddr, hwcfg);
- dma_wrreg(chan, S3C2410_DMA_DISRCC, hwcfg & 3);
- dma_wrreg(chan, S3C2410_DMA_DISRC, devaddr);
- dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0));
-
- chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
- break;
-
- case DMA_TO_DEVICE:
- /* source is memory */
- pr_debug("%s: mem source, devaddr=%08lx, hwcfg=%d\n",
- __func__, devaddr, hwcfg);
- dma_wrreg(chan, S3C2410_DMA_DISRCC, (0<<1) | (0<<0));
- dma_wrreg(chan, S3C2410_DMA_DIDST, devaddr);
- dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3);
-
- chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC);
- break;
-
- default:
- printk(KERN_ERR "dma%d: invalid source type (%d)\n",
- channel, source);
-
- return -EINVAL;
- }
-
- return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_devconfig);
-
-/* s3c2410_dma_getposition
- *
- * returns the current transfer points for the dma source and destination
-*/
-
-int s3c2410_dma_getposition(enum dma_ch channel, dma_addr_t *src, dma_addr_t *dst)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
- if (chan == NULL)
- return -EINVAL;
-
- if (src != NULL)
- *src = dma_rdreg(chan, S3C2410_DMA_DCSRC);
-
- if (dst != NULL)
- *dst = dma_rdreg(chan, S3C2410_DMA_DCDST);
-
- return 0;
-}
-
-EXPORT_SYMBOL(s3c2410_dma_getposition);
-
-/* system core operations */
-
-#ifdef CONFIG_PM
-
-static void s3c2410_dma_suspend_chan(struct s3c2410_dma_chan *cp)
-{
- printk(KERN_DEBUG "suspending dma channel %d\n", cp->number);
-
- if (dma_rdreg(cp, S3C2410_DMA_DMASKTRIG) & S3C2410_DMASKTRIG_ON) {
- /* the dma channel is still working, which is probably
- * a bad thing to do over suspend/resume. We stop the
- * channel and assume that the client is either going to
- * retry after resume, or that it is broken.
- */
-
- printk(KERN_INFO "dma: stopping channel %d due to suspend\n",
- cp->number);
-
- s3c2410_dma_dostop(cp);
- }
-}
-
-static int s3c2410_dma_suspend(void)
-{
- struct s3c2410_dma_chan *cp = s3c2410_chans;
- int channel;
-
- for (channel = 0; channel < dma_channels; cp++, channel++)
- s3c2410_dma_suspend_chan(cp);
-
- return 0;
-}
-
-static void s3c2410_dma_resume_chan(struct s3c2410_dma_chan *cp)
-{
- unsigned int no = cp->number | DMACH_LOW_LEVEL;
-
- /* restore channel's hardware configuration */
-
- if (!cp->in_use)
- return;
-
- printk(KERN_INFO "dma%d: restoring configuration\n", cp->number);
-
- s3c2410_dma_config(no, cp->xfer_unit);
- s3c2410_dma_devconfig(no, cp->source, cp->dev_addr);
-
- /* re-select the dma source for this channel */
-
- if (cp->map != NULL)
- dma_sel.select(cp, cp->map);
-}
-
-static void s3c2410_dma_resume(void)
-{
- struct s3c2410_dma_chan *cp = s3c2410_chans + dma_channels - 1;
- int channel;
-
- for (channel = dma_channels - 1; channel >= 0; cp--, channel--)
- s3c2410_dma_resume_chan(cp);
-}
-
-#else
-#define s3c2410_dma_suspend NULL
-#define s3c2410_dma_resume NULL
-#endif /* CONFIG_PM */
-
-struct syscore_ops dma_syscore_ops = {
- .suspend = s3c2410_dma_suspend,
- .resume = s3c2410_dma_resume,
-};
-
-/* kmem cache implementation */
-
-static void s3c2410_dma_cache_ctor(void *p)
-{
- memset(p, 0, sizeof(struct s3c2410_dma_buf));
-}
-
-/* initialisation code */
-
-static int __init s3c24xx_dma_syscore_init(void)
-{
- register_syscore_ops(&dma_syscore_ops);
-
- return 0;
-}
-
-late_initcall(s3c24xx_dma_syscore_init);
-
-int __init s3c24xx_dma_init(unsigned int channels, unsigned int irq,
- unsigned int stride)
-{
- struct s3c2410_dma_chan *cp;
- int channel;
- int ret;
-
- printk("S3C24XX DMA Driver, Copyright 2003-2006 Simtec Electronics\n");
-
- dma_channels = channels;
-
- dma_base = ioremap(S3C24XX_PA_DMA, stride * channels);
- if (dma_base == NULL) {
- printk(KERN_ERR "dma failed to remap register block\n");
- return -ENOMEM;
- }
-
- dma_kmem = kmem_cache_create("dma_desc",
- sizeof(struct s3c2410_dma_buf), 0,
- SLAB_HWCACHE_ALIGN,
- s3c2410_dma_cache_ctor);
-
- if (dma_kmem == NULL) {
- printk(KERN_ERR "dma failed to make kmem cache\n");
- ret = -ENOMEM;
- goto err;
- }
-
- for (channel = 0; channel < channels; channel++) {
- cp = &s3c2410_chans[channel];
-
- memset(cp, 0, sizeof(struct s3c2410_dma_chan));
-
- /* dma channel irqs are in order.. */
- cp->number = channel;
- cp->irq = channel + irq;
- cp->regs = dma_base + (channel * stride);
-
- /* point current stats somewhere */
- cp->stats = &cp->stats_store;
- cp->stats_store.timeout_shortest = LONG_MAX;
-
- /* basic channel configuration */
-
- cp->load_timeout = 1<<18;
-
- printk("DMA channel %d at %p, irq %d\n",
- cp->number, cp->regs, cp->irq);
- }
-
- return 0;
-
- err:
- kmem_cache_destroy(dma_kmem);
- iounmap(dma_base);
- dma_base = NULL;
- return ret;
-}
-
-int __init s3c2410_dma_init(void)
-{
- return s3c24xx_dma_init(4, IRQ_DMA0, 0x40);
-}
-
-static inline int is_channel_valid(unsigned int channel)
-{
- return (channel & DMA_CH_VALID);
-}
-
-static struct s3c24xx_dma_order *dma_order;
-
-
-/* s3c2410_dma_map_channel()
- *
- * turn the virtual channel number into a real, and un-used hardware
- * channel.
- *
- * first, try the dma ordering given to us by either the relevant
- * dma code, or the board. Then just find the first usable free
- * channel
-*/
-
-static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
-{
- struct s3c24xx_dma_order_ch *ord = NULL;
- struct s3c24xx_dma_map *ch_map;
- struct s3c2410_dma_chan *dmach;
- int ch;
-
- if (dma_sel.map == NULL || channel > dma_sel.map_size)
- return NULL;
-
- ch_map = dma_sel.map + channel;
-
- /* first, try the board mapping */
-
- if (dma_order) {
- ord = &dma_order->channels[channel];
-
- for (ch = 0; ch < dma_channels; ch++) {
- int tmp;
- if (!is_channel_valid(ord->list[ch]))
- continue;
-
- tmp = ord->list[ch] & ~DMA_CH_VALID;
- if (s3c2410_chans[tmp].in_use == 0) {
- ch = tmp;
- goto found;
- }
- }
-
- if (ord->flags & DMA_CH_NEVER)
- return NULL;
- }
-
- /* second, search the channel map for first free */
-
- for (ch = 0; ch < dma_channels; ch++) {
- if (!is_channel_valid(ch_map->channels[ch]))
- continue;
-
- if (s3c2410_chans[ch].in_use == 0) {
- printk("mapped channel %d to %d\n", channel, ch);
- break;
- }
- }
-
- if (ch >= dma_channels)
- return NULL;
-
- /* update our channel mapping */
-
- found:
- dmach = &s3c2410_chans[ch];
- dmach->map = ch_map;
- dmach->req_ch = channel;
- s3c_dma_chan_map[channel] = dmach;
-
- /* select the channel */
-
- (dma_sel.select)(dmach, ch_map);
-
- return dmach;
-}
-
-static int s3c24xx_dma_check_entry(struct s3c24xx_dma_map *map, int ch)
-{
- return 0;
-}
-
-int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel)
-{
- struct s3c24xx_dma_map *nmap;
- size_t map_sz = sizeof(*nmap) * sel->map_size;
- int ptr;
-
- nmap = kmemdup(sel->map, map_sz, GFP_KERNEL);
- if (nmap == NULL)
- return -ENOMEM;
-
- memcpy(&dma_sel, sel, sizeof(*sel));
-
- dma_sel.map = nmap;
-
- for (ptr = 0; ptr < sel->map_size; ptr++)
- s3c24xx_dma_check_entry(nmap+ptr, ptr);
-
- return 0;
-}
-
-int __init s3c24xx_dma_order_set(struct s3c24xx_dma_order *ord)
-{
- struct s3c24xx_dma_order *nord = dma_order;
-
- if (nord == NULL)
- nord = kmalloc(sizeof(struct s3c24xx_dma_order), GFP_KERNEL);
-
- if (nord == NULL) {
- printk(KERN_ERR "no memory to store dma channel order\n");
- return -ENOMEM;
- }
-
- dma_order = nord;
- memcpy(nord, ord, sizeof(struct s3c24xx_dma_order));
- return 0;
-}
diff --git a/arch/arm/mach-s3c24xx/include/mach/dma.h b/arch/arm/mach-s3c24xx/include/mach/dma.h
index b55da1d8cd8f..9e8117198e0c 100644
--- a/arch/arm/mach-s3c24xx/include/mach/dma.h
+++ b/arch/arm/mach-s3c24xx/include/mach/dma.h
@@ -15,8 +15,6 @@
#include <linux/device.h>
-#define MAX_DMA_TRANSFER_SIZE 0x100000 /* Data Unit is half word */
-
/* We use `virtual` dma channels to hide the fact we have only a limited
* number of DMA channels, and not of all of them (dependent on the device)
* can be attached to any DMA source. We therefore let the DMA core handle
@@ -54,161 +52,4 @@ enum dma_ch {
DMACH_MAX, /* the end entry */
};
-static inline bool samsung_dma_has_circular(void)
-{
- return false;
-}
-
-static inline bool samsung_dma_is_dmadev(void)
-{
- return false;
-}
-
-#include <plat/dma.h>
-
-#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
-
-/* we have 4 dma channels */
-#if !defined(CONFIG_CPU_S3C2443) && !defined(CONFIG_CPU_S3C2416)
-#define S3C_DMA_CHANNELS (4)
-#else
-#define S3C_DMA_CHANNELS (6)
-#endif
-
-/* types */
-
-enum s3c2410_dma_state {
- S3C2410_DMA_IDLE,
- S3C2410_DMA_RUNNING,
- S3C2410_DMA_PAUSED
-};
-
-/* enum s3c2410_dma_loadst
- *
- * This represents the state of the DMA engine, wrt to the loaded / running
- * transfers. Since we don't have any way of knowing exactly the state of
- * the DMA transfers, we need to know the state to make decisions on whether
- * we can
- *
- * S3C2410_DMA_NONE
- *
- * There are no buffers loaded (the channel should be inactive)
- *
- * S3C2410_DMA_1LOADED
- *
- * There is one buffer loaded, however it has not been confirmed to be
- * loaded by the DMA engine. This may be because the channel is not
- * yet running, or the DMA driver decided that it was too costly to
- * sit and wait for it to happen.
- *
- * S3C2410_DMA_1RUNNING
- *
- * The buffer has been confirmed running, and not finisged
- *
- * S3C2410_DMA_1LOADED_1RUNNING
- *
- * There is a buffer waiting to be loaded by the DMA engine, and one
- * currently running.
-*/
-
-enum s3c2410_dma_loadst {
- S3C2410_DMALOAD_NONE,
- S3C2410_DMALOAD_1LOADED,
- S3C2410_DMALOAD_1RUNNING,
- S3C2410_DMALOAD_1LOADED_1RUNNING,
-};
-
-
-/* flags */
-
-#define S3C2410_DMAF_SLOW (1<<0) /* slow, so don't worry about
- * waiting for reloads */
-#define S3C2410_DMAF_AUTOSTART (1<<1) /* auto-start if buffer queued */
-
-#define S3C2410_DMAF_CIRCULAR (1 << 2) /* no circular dma support */
-
-/* dma buffer */
-
-struct s3c2410_dma_buf;
-
-/* s3c2410_dma_buf
- *
- * internally used buffer structure to describe a queued or running
- * buffer.
-*/
-
-struct s3c2410_dma_buf {
- struct s3c2410_dma_buf *next;
- int magic; /* magic */
- int size; /* buffer size in bytes */
- dma_addr_t data; /* start of DMA data */
- dma_addr_t ptr; /* where the DMA got to [1] */
- void *id; /* client's id */
-};
-
-/* [1] is this updated for both recv/send modes? */
-
-struct s3c2410_dma_stats {
- unsigned long loads;
- unsigned long timeout_longest;
- unsigned long timeout_shortest;
- unsigned long timeout_avg;
- unsigned long timeout_failed;
-};
-
-struct s3c2410_dma_map;
-
-/* struct s3c2410_dma_chan
- *
- * full state information for each DMA channel
-*/
-
-struct s3c2410_dma_chan {
- /* channel state flags and information */
- unsigned char number; /* number of this dma channel */
- unsigned char in_use; /* channel allocated */
- unsigned char irq_claimed; /* irq claimed for channel */
- unsigned char irq_enabled; /* irq enabled for channel */
- unsigned char xfer_unit; /* size of an transfer */
-
- /* channel state */
-
- enum s3c2410_dma_state state;
- enum s3c2410_dma_loadst load_state;
- struct s3c2410_dma_client *client;
-
- /* channel configuration */
- enum dma_data_direction source;
- enum dma_ch req_ch;
- unsigned long dev_addr;
- unsigned long load_timeout;
- unsigned int flags; /* channel flags */
-
- struct s3c24xx_dma_map *map; /* channel hw maps */
-
- /* channel's hardware position and configuration */
- void __iomem *regs; /* channels registers */
- void __iomem *addr_reg; /* data address register */
- unsigned int irq; /* channel irq */
- unsigned long dcon; /* default value of DCON */
-
- /* driver handles */
- s3c2410_dma_cbfn_t callback_fn; /* buffer done callback */
- s3c2410_dma_opfn_t op_fn; /* channel op callback */
-
- /* stats gathering */
- struct s3c2410_dma_stats *stats;
- struct s3c2410_dma_stats stats_store;
-
- /* buffer list and information */
- struct s3c2410_dma_buf *curr; /* current dma buffer */
- struct s3c2410_dma_buf *next; /* next buffer to load */
- struct s3c2410_dma_buf *end; /* end of queue */
-
- /* system device */
- struct device dev;
-};
-
-typedef unsigned long dma_device_t;
-
#endif /* __ASM_ARCH_DMA_H */
diff --git a/arch/arm/mach-s3c64xx/include/mach/dma.h b/arch/arm/mach-s3c64xx/include/mach/dma.h
index 059b1fc85037..096e14073bd9 100644
--- a/arch/arm/mach-s3c64xx/include/mach/dma.h
+++ b/arch/arm/mach-s3c64xx/include/mach/dma.h
@@ -51,21 +51,6 @@ enum dma_ch {
DMACH_MAX = 32
};
-struct s3c2410_dma_client {
- char *name;
-};
-
-static inline bool samsung_dma_has_circular(void)
-{
- return true;
-}
-
-static inline bool samsung_dma_is_dmadev(void)
-{
- return true;
-}
-
#include <linux/amba/pl08x.h>
-#include <plat/dma-ops.h>
#endif /* __ASM_ARCH_IRQ_H */
diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile
index f1114d11fe13..61ff91e76e0a 100644
--- a/arch/arm/mach-sa1100/Makefile
+++ b/arch/arm/mach-sa1100/Makefile
@@ -3,7 +3,7 @@
#
# Common support
-obj-y := clock.o generic.o irq.o time.o #nmi-oopser.o
+obj-y := clock.o generic.o irq.o #nmi-oopser.o
# Specific board support
obj-$(CONFIG_SA1100_ASSABET) += assabet.o
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 7dd894ece9ae..d28ecb9ef172 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -37,7 +37,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
-#include <asm/mach/irda.h>
+#include <linux/platform_data/irda-sa11x0.h>
#include <asm/mach/map.h>
#include <mach/assabet.h>
#include <linux/platform_data/mfd-mcp-sa11x0.h>
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
index 03c75a811cb0..cbf53bb9c814 100644
--- a/arch/arm/mach-sa1100/clock.c
+++ b/arch/arm/mach-sa1100/clock.c
@@ -119,6 +119,17 @@ static DEFINE_CLK(gpio27, &clk_gpio27_ops);
static DEFINE_CLK(cpu, &clk_cpu_ops);
+static unsigned long clk_36864_get_rate(struct clk *clk)
+{
+ return 3686400;
+}
+
+static struct clkops clk_36864_ops = {
+ .get_rate = clk_36864_get_rate,
+};
+
+static DEFINE_CLK(36864, &clk_36864_ops);
+
static struct clk_lookup sa11xx_clkregs[] = {
CLKDEV_INIT("sa1111.0", NULL, &clk_gpio27),
CLKDEV_INIT("sa1100-rtc", NULL, NULL),
@@ -126,6 +137,7 @@ static struct clk_lookup sa11xx_clkregs[] = {
CLKDEV_INIT("sa11x0-pcmcia", NULL, &clk_cpu),
/* sa1111 names devices using internal offsets, PCMCIA is at 0x1800 */
CLKDEV_INIT("1800", NULL, &clk_cpu),
+ CLKDEV_INIT(NULL, "OSTIMER0", &clk_36864),
};
static int __init sa11xx_clk_init(void)
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index b90c7d828391..3cc2b71e16f0 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -43,7 +43,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
-#include <asm/mach/irda.h>
+#include <linux/platform_data/irda-sa11x0.h>
#include <asm/hardware/scoop.h>
#include <asm/mach/sharpsl_param.h>
@@ -371,8 +371,7 @@ static void __init collie_init(void)
PPC_LDD6 | PPC_LDD7 | PPC_L_PCLK | PPC_L_LCLK | PPC_L_FCLK | PPC_L_BIAS |
PPC_TXD1 | PPC_TXD2 | PPC_TXD3 | PPC_TXD4 | PPC_SCLK | PPC_SFRM;
- PWER = _COLLIE_GPIO_AC_IN | _COLLIE_GPIO_CO | _COLLIE_GPIO_ON_KEY |
- _COLLIE_GPIO_WAKEUP | _COLLIE_GPIO_nREMOCON_INT | PWER_RTC;
+ PWER = 0;
PGSR = _COLLIE_GPIO_nREMOCON_ON;
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
index d4ea142c4edd..40e0d8619a2d 100644
--- a/arch/arm/mach-sa1100/generic.c
+++ b/arch/arm/mach-sa1100/generic.c
@@ -33,6 +33,7 @@
#include <mach/irqs.h>
#include "generic.h"
+#include <clocksource/pxa.h>
unsigned int reset_status;
EXPORT_SYMBOL(reset_status);
@@ -369,6 +370,11 @@ void __init sa1100_map_io(void)
iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
}
+void __init sa1100_timer_init(void)
+{
+ pxa_timer_nodt_init(IRQ_OST0, io_p2v(0x90000000), 3686400);
+}
+
/*
* Disable the memory bus request/grant signals on the SA1110 to
* ensure that we don't receive spurious memory requests. We set
diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c
index 3c43219bc881..c6b412054a3c 100644
--- a/arch/arm/mach-sa1100/h3100.c
+++ b/arch/arm/mach-sa1100/h3100.c
@@ -18,7 +18,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <asm/mach/irda.h>
+#include <linux/platform_data/irda-sa11x0.h>
#include <mach/h3xxx.h>
#include <mach/irqs.h>
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index 5be54c214c7c..118338efd790 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -18,7 +18,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <asm/mach/irda.h>
+#include <linux/platform_data/irda-sa11x0.h>
#include <mach/h3xxx.h>
#include <mach/irqs.h>
diff --git a/arch/arm/mach-sa1100/include/mach/irqs.h b/arch/arm/mach-sa1100/include/mach/irqs.h
index de0983494c7e..734e30e406a3 100644
--- a/arch/arm/mach-sa1100/include/mach/irqs.h
+++ b/arch/arm/mach-sa1100/include/mach/irqs.h
@@ -8,17 +8,17 @@
* 2001/11/14 RMK Cleaned up and standardised a lot of the IRQs.
*/
-#define IRQ_GPIO0 1
-#define IRQ_GPIO1 2
-#define IRQ_GPIO2 3
-#define IRQ_GPIO3 4
-#define IRQ_GPIO4 5
-#define IRQ_GPIO5 6
-#define IRQ_GPIO6 7
-#define IRQ_GPIO7 8
-#define IRQ_GPIO8 9
-#define IRQ_GPIO9 10
-#define IRQ_GPIO10 11
+#define IRQ_GPIO0_SC 1
+#define IRQ_GPIO1_SC 2
+#define IRQ_GPIO2_SC 3
+#define IRQ_GPIO3_SC 4
+#define IRQ_GPIO4_SC 5
+#define IRQ_GPIO5_SC 6
+#define IRQ_GPIO6_SC 7
+#define IRQ_GPIO7_SC 8
+#define IRQ_GPIO8_SC 9
+#define IRQ_GPIO9_SC 10
+#define IRQ_GPIO10_SC 11
#define IRQ_GPIO11_27 12
#define IRQ_LCD 13 /* LCD controller */
#define IRQ_Ser0UDC 14 /* Ser. port 0 UDC */
@@ -41,32 +41,43 @@
#define IRQ_RTC1Hz 31 /* RTC 1 Hz clock */
#define IRQ_RTCAlrm 32 /* RTC Alarm */
-#define IRQ_GPIO11 33
-#define IRQ_GPIO12 34
-#define IRQ_GPIO13 35
-#define IRQ_GPIO14 36
-#define IRQ_GPIO15 37
-#define IRQ_GPIO16 38
-#define IRQ_GPIO17 39
-#define IRQ_GPIO18 40
-#define IRQ_GPIO19 41
-#define IRQ_GPIO20 42
-#define IRQ_GPIO21 43
-#define IRQ_GPIO22 44
-#define IRQ_GPIO23 45
-#define IRQ_GPIO24 46
-#define IRQ_GPIO25 47
-#define IRQ_GPIO26 48
-#define IRQ_GPIO27 49
+#define IRQ_GPIO0 33
+#define IRQ_GPIO1 34
+#define IRQ_GPIO2 35
+#define IRQ_GPIO3 36
+#define IRQ_GPIO4 37
+#define IRQ_GPIO5 38
+#define IRQ_GPIO6 39
+#define IRQ_GPIO7 40
+#define IRQ_GPIO8 41
+#define IRQ_GPIO9 42
+#define IRQ_GPIO10 43
+#define IRQ_GPIO11 44
+#define IRQ_GPIO12 45
+#define IRQ_GPIO13 46
+#define IRQ_GPIO14 47
+#define IRQ_GPIO15 48
+#define IRQ_GPIO16 49
+#define IRQ_GPIO17 50
+#define IRQ_GPIO18 51
+#define IRQ_GPIO19 52
+#define IRQ_GPIO20 53
+#define IRQ_GPIO21 54
+#define IRQ_GPIO22 55
+#define IRQ_GPIO23 56
+#define IRQ_GPIO24 57
+#define IRQ_GPIO25 58
+#define IRQ_GPIO26 59
+#define IRQ_GPIO27 60
/*
* The next 16 interrupts are for board specific purposes. Since
* the kernel can only run on one machine at a time, we can re-use
* these. If you need more, increase IRQ_BOARD_END, but keep it
- * within sensible limits. IRQs 49 to 64 are available.
+ * within sensible limits. IRQs 61 to 76 are available.
*/
-#define IRQ_BOARD_START 50
-#define IRQ_BOARD_END 66
+#define IRQ_BOARD_START 61
+#define IRQ_BOARD_END 77
/*
* Figure out the MAX IRQ number.
diff --git a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
index 63e2901db416..65aebfa66fe5 100644
--- a/arch/arm/mach-sa1100/irq.c
+++ b/arch/arm/mach-sa1100/irq.c
@@ -80,170 +80,6 @@ static struct irq_domain_ops sa1100_normal_irqdomain_ops = {
static struct irq_domain *sa1100_normal_irqdomain;
-/*
- * SA1100 GPIO edge detection for IRQs:
- * IRQs are generated on Falling-Edge, Rising-Edge, or both.
- * Use this instead of directly setting GRER/GFER.
- */
-static int GPIO_IRQ_rising_edge;
-static int GPIO_IRQ_falling_edge;
-static int GPIO_IRQ_mask = (1 << 11) - 1;
-
-static int sa1100_gpio_type(struct irq_data *d, unsigned int type)
-{
- unsigned int mask;
-
- mask = BIT(d->hwirq);
-
- if (type == IRQ_TYPE_PROBE) {
- if ((GPIO_IRQ_rising_edge | GPIO_IRQ_falling_edge) & mask)
- return 0;
- type = IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING;
- }
-
- if (type & IRQ_TYPE_EDGE_RISING) {
- GPIO_IRQ_rising_edge |= mask;
- } else
- GPIO_IRQ_rising_edge &= ~mask;
- if (type & IRQ_TYPE_EDGE_FALLING) {
- GPIO_IRQ_falling_edge |= mask;
- } else
- GPIO_IRQ_falling_edge &= ~mask;
-
- GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
- GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
-
- return 0;
-}
-
-/*
- * GPIO IRQs must be acknowledged.
- */
-static void sa1100_gpio_ack(struct irq_data *d)
-{
- GEDR = BIT(d->hwirq);
-}
-
-static int sa1100_gpio_wake(struct irq_data *d, unsigned int on)
-{
- if (on)
- PWER |= BIT(d->hwirq);
- else
- PWER &= ~BIT(d->hwirq);
- return 0;
-}
-
-/*
- * This is for IRQs from 0 to 10.
- */
-static struct irq_chip sa1100_low_gpio_chip = {
- .name = "GPIO-l",
- .irq_ack = sa1100_gpio_ack,
- .irq_mask = sa1100_mask_irq,
- .irq_unmask = sa1100_unmask_irq,
- .irq_set_type = sa1100_gpio_type,
- .irq_set_wake = sa1100_gpio_wake,
-};
-
-static int sa1100_low_gpio_irqdomain_map(struct irq_domain *d,
- unsigned int irq, irq_hw_number_t hwirq)
-{
- irq_set_chip_and_handler(irq, &sa1100_low_gpio_chip,
- handle_edge_irq);
- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-
- return 0;
-}
-
-static struct irq_domain_ops sa1100_low_gpio_irqdomain_ops = {
- .map = sa1100_low_gpio_irqdomain_map,
- .xlate = irq_domain_xlate_onetwocell,
-};
-
-static struct irq_domain *sa1100_low_gpio_irqdomain;
-
-/*
- * IRQ11 (GPIO11 through 27) handler. We enter here with the
- * irq_controller_lock held, and IRQs disabled. Decode the IRQ
- * and call the handler.
- */
-static void
-sa1100_high_gpio_handler(unsigned int irq, struct irq_desc *desc)
-{
- unsigned int mask;
-
- mask = GEDR & 0xfffff800;
- do {
- /*
- * clear down all currently active IRQ sources.
- * We will be processing them all.
- */
- GEDR = mask;
-
- irq = IRQ_GPIO11;
- mask >>= 11;
- do {
- if (mask & 1)
- generic_handle_irq(irq);
- mask >>= 1;
- irq++;
- } while (mask);
-
- mask = GEDR & 0xfffff800;
- } while (mask);
-}
-
-/*
- * Like GPIO0 to 10, GPIO11-27 IRQs need to be handled specially.
- * In addition, the IRQs are all collected up into one bit in the
- * interrupt controller registers.
- */
-static void sa1100_high_gpio_mask(struct irq_data *d)
-{
- unsigned int mask = BIT(d->hwirq);
-
- GPIO_IRQ_mask &= ~mask;
-
- GRER &= ~mask;
- GFER &= ~mask;
-}
-
-static void sa1100_high_gpio_unmask(struct irq_data *d)
-{
- unsigned int mask = BIT(d->hwirq);
-
- GPIO_IRQ_mask |= mask;
-
- GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
- GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
-}
-
-static struct irq_chip sa1100_high_gpio_chip = {
- .name = "GPIO-h",
- .irq_ack = sa1100_gpio_ack,
- .irq_mask = sa1100_high_gpio_mask,
- .irq_unmask = sa1100_high_gpio_unmask,
- .irq_set_type = sa1100_gpio_type,
- .irq_set_wake = sa1100_gpio_wake,
-};
-
-static int sa1100_high_gpio_irqdomain_map(struct irq_domain *d,
- unsigned int irq, irq_hw_number_t hwirq)
-{
- irq_set_chip_and_handler(irq, &sa1100_high_gpio_chip,
- handle_edge_irq);
- set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-
- return 0;
-}
-
-static struct irq_domain_ops sa1100_high_gpio_irqdomain_ops = {
- .map = sa1100_high_gpio_irqdomain_map,
- .xlate = irq_domain_xlate_onetwocell,
-};
-
-static struct irq_domain *sa1100_high_gpio_irqdomain;
-
static struct resource irq_resource =
DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs");
@@ -270,17 +106,6 @@ static int sa1100irq_suspend(void)
IC_GPIO6|IC_GPIO5|IC_GPIO4|IC_GPIO3|IC_GPIO2|
IC_GPIO1|IC_GPIO0);
- /*
- * Set the appropriate edges for wakeup.
- */
- GRER = PWER & GPIO_IRQ_rising_edge;
- GFER = PWER & GPIO_IRQ_falling_edge;
-
- /*
- * Clear any pending GPIO interrupts.
- */
- GEDR = GEDR;
-
return 0;
}
@@ -292,9 +117,6 @@ static void sa1100irq_resume(void)
ICCR = st->iccr;
ICLR = st->iclr;
- GRER = GPIO_IRQ_rising_edge & GPIO_IRQ_mask;
- GFER = GPIO_IRQ_falling_edge & GPIO_IRQ_mask;
-
ICMR = st->icmr;
}
}
@@ -325,7 +147,8 @@ sa1100_handle_irq(struct pt_regs *regs)
if (mask == 0)
break;
- handle_IRQ(ffs(mask) - 1 + IRQ_GPIO0, regs);
+ handle_domain_irq(sa1100_normal_irqdomain,
+ ffs(mask) - 1, regs);
} while (1);
}
@@ -339,34 +162,16 @@ void __init sa1100_init_irq(void)
/* all IRQs are IRQ, not FIQ */
ICLR = 0;
- /* clear all GPIO edge detects */
- GFER = 0;
- GRER = 0;
- GEDR = -1;
-
/*
* Whatever the doc says, this has to be set for the wait-on-irq
* instruction to work... on a SA1100 rev 9 at least.
*/
ICCR = 1;
- sa1100_low_gpio_irqdomain = irq_domain_add_legacy(NULL,
- 11, IRQ_GPIO0, 0,
- &sa1100_low_gpio_irqdomain_ops, NULL);
-
- sa1100_normal_irqdomain = irq_domain_add_legacy(NULL,
- 21, IRQ_GPIO11_27, 11,
+ sa1100_normal_irqdomain = irq_domain_add_simple(NULL,
+ 32, IRQ_GPIO0_SC,
&sa1100_normal_irqdomain_ops, NULL);
- sa1100_high_gpio_irqdomain = irq_domain_add_legacy(NULL,
- 17, IRQ_GPIO11, 11,
- &sa1100_high_gpio_irqdomain_ops, NULL);
-
- /*
- * Install handler for GPIO 11-27 edge detect interrupts
- */
- irq_set_chained_handler(IRQ_GPIO11_27, sa1100_high_gpio_handler);
-
set_handle_irq(sa1100_handle_irq);
sa1100_init_gpio();
diff --git a/arch/arm/mach-sa1100/pci-nanoengine.c b/arch/arm/mach-sa1100/pci-nanoengine.c
index b704433c529c..d7ae8d50f6d8 100644
--- a/arch/arm/mach-sa1100/pci-nanoengine.c
+++ b/arch/arm/mach-sa1100/pci-nanoengine.c
@@ -22,7 +22,6 @@
#include <linux/kernel.h>
#include <linux/irq.h>
#include <linux/pci.h>
-#include <linux/spinlock.h>
#include <asm/mach/pci.h>
#include <asm/mach-types.h>
@@ -30,97 +29,20 @@
#include <mach/nanoengine.h>
#include <mach/hardware.h>
-static DEFINE_SPINLOCK(nano_lock);
-
-static int nanoengine_get_pci_address(struct pci_bus *bus,
- unsigned int devfn, int where, void __iomem **address)
+static void __iomem *nanoengine_pci_map_bus(struct pci_bus *bus,
+ unsigned int devfn, int where)
{
- int ret = PCIBIOS_DEVICE_NOT_FOUND;
- unsigned int busnr = bus->number;
+ if (bus->number != 0 || (devfn >> 3) != 0)
+ return NULL;
- *address = (void __iomem *)NANO_PCI_CONFIG_SPACE_VIRT +
+ return (void __iomem *)NANO_PCI_CONFIG_SPACE_VIRT +
((bus->number << 16) | (devfn << 8) | (where & ~3));
-
- ret = (busnr > 255 || devfn > 255 || where > 255) ?
- PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
-
- return ret;
-}
-
-static int nanoengine_read_config(struct pci_bus *bus, unsigned int devfn, int where,
- int size, u32 *val)
-{
- int ret;
- void __iomem *address;
- unsigned long flags;
- u32 v;
-
- /* nanoEngine PCI bridge does not return -1 for a non-existing
- * device. We must fake the answer. We know that the only valid
- * device is device zero at bus 0, which is the network chip. */
- if (bus->number != 0 || (devfn >> 3) != 0) {
- v = -1;
- nanoengine_get_pci_address(bus, devfn, where, &address);
- goto exit_function;
- }
-
- spin_lock_irqsave(&nano_lock, flags);
-
- ret = nanoengine_get_pci_address(bus, devfn, where, &address);
- if (ret != PCIBIOS_SUCCESSFUL)
- return ret;
- v = __raw_readl(address);
-
- spin_unlock_irqrestore(&nano_lock, flags);
-
- v >>= ((where & 3) * 8);
- v &= (unsigned long)(-1) >> ((4 - size) * 8);
-
-exit_function:
- *val = v;
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int nanoengine_write_config(struct pci_bus *bus, unsigned int devfn, int where,
- int size, u32 val)
-{
- int ret;
- void __iomem *address;
- unsigned long flags;
- unsigned shift;
- u32 v;
-
- shift = (where & 3) * 8;
-
- spin_lock_irqsave(&nano_lock, flags);
-
- ret = nanoengine_get_pci_address(bus, devfn, where, &address);
- if (ret != PCIBIOS_SUCCESSFUL)
- return ret;
- v = __raw_readl(address);
- switch (size) {
- case 1:
- v &= ~(0xFF << shift);
- v |= val << shift;
- break;
- case 2:
- v &= ~(0xFFFF << shift);
- v |= val << shift;
- break;
- case 4:
- v = val;
- break;
- }
- __raw_writel(v, address);
-
- spin_unlock_irqrestore(&nano_lock, flags);
-
- return PCIBIOS_SUCCESSFUL;
}
static struct pci_ops pci_nano_ops = {
- .read = nanoengine_read_config,
- .write = nanoengine_write_config,
+ .map_bus = nanoengine_pci_map_bus,
+ .read = pci_generic_config_read32,
+ .write = pci_generic_config_write32,
};
static int __init pci_nanoengine_map_irq(const struct pci_dev *dev, u8 slot,
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
index 6645d1e31f14..34853d5dfda2 100644
--- a/arch/arm/mach-sa1100/pm.c
+++ b/arch/arm/mach-sa1100/pm.c
@@ -81,6 +81,7 @@ static int sa11x0_pm_enter(suspend_state_t state)
/*
* Ensure not to come back here if it wasn't intended
*/
+ RCSR = RCSR_SMR;
PSPR = 0;
/*
diff --git a/arch/arm/mach-sa1100/time.c b/arch/arm/mach-sa1100/time.c
deleted file mode 100644
index 1dea6cfafb31..000000000000
--- a/arch/arm/mach-sa1100/time.c
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * linux/arch/arm/mach-sa1100/time.c
- *
- * Copyright (C) 1998 Deborah Wallach.
- * Twiddles (C) 1999 Hugo Fiennes <hugo@empeg.com>
- *
- * 2000/03/29 (C) Nicolas Pitre <nico@fluxnic.net>
- * Rewritten: big cleanup, much simpler, better HZ accuracy.
- *
- */
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/timex.h>
-#include <linux/clockchips.h>
-#include <linux/sched_clock.h>
-
-#include <asm/mach/time.h>
-#include <mach/hardware.h>
-#include <mach/irqs.h>
-
-#define SA1100_CLOCK_FREQ 3686400
-#define SA1100_LATCH DIV_ROUND_CLOSEST(SA1100_CLOCK_FREQ, HZ)
-
-static u64 notrace sa1100_read_sched_clock(void)
-{
- return readl_relaxed(OSCR);
-}
-
-#define MIN_OSCR_DELTA 2
-
-static irqreturn_t sa1100_ost0_interrupt(int irq, void *dev_id)
-{
- struct clock_event_device *c = dev_id;
-
- /* Disarm the compare/match, signal the event. */
- writel_relaxed(readl_relaxed(OIER) & ~OIER_E0, OIER);
- writel_relaxed(OSSR_M0, OSSR);
- c->event_handler(c);
-
- return IRQ_HANDLED;
-}
-
-static int
-sa1100_osmr0_set_next_event(unsigned long delta, struct clock_event_device *c)
-{
- unsigned long next, oscr;
-
- writel_relaxed(readl_relaxed(OIER) | OIER_E0, OIER);
- next = readl_relaxed(OSCR) + delta;
- writel_relaxed(next, OSMR0);
- oscr = readl_relaxed(OSCR);
-
- return (signed)(next - oscr) <= MIN_OSCR_DELTA ? -ETIME : 0;
-}
-
-static void
-sa1100_osmr0_set_mode(enum clock_event_mode mode, struct clock_event_device *c)
-{
- switch (mode) {
- case CLOCK_EVT_MODE_ONESHOT:
- case CLOCK_EVT_MODE_UNUSED:
- case CLOCK_EVT_MODE_SHUTDOWN:
- writel_relaxed(readl_relaxed(OIER) & ~OIER_E0, OIER);
- writel_relaxed(OSSR_M0, OSSR);
- break;
-
- case CLOCK_EVT_MODE_RESUME:
- case CLOCK_EVT_MODE_PERIODIC:
- break;
- }
-}
-
-#ifdef CONFIG_PM
-unsigned long osmr[4], oier;
-
-static void sa1100_timer_suspend(struct clock_event_device *cedev)
-{
- osmr[0] = readl_relaxed(OSMR0);
- osmr[1] = readl_relaxed(OSMR1);
- osmr[2] = readl_relaxed(OSMR2);
- osmr[3] = readl_relaxed(OSMR3);
- oier = readl_relaxed(OIER);
-}
-
-static void sa1100_timer_resume(struct clock_event_device *cedev)
-{
- writel_relaxed(0x0f, OSSR);
- writel_relaxed(osmr[0], OSMR0);
- writel_relaxed(osmr[1], OSMR1);
- writel_relaxed(osmr[2], OSMR2);
- writel_relaxed(osmr[3], OSMR3);
- writel_relaxed(oier, OIER);
-
- /*
- * OSMR0 is the system timer: make sure OSCR is sufficiently behind
- */
- writel_relaxed(OSMR0 - SA1100_LATCH, OSCR);
-}
-#else
-#define sa1100_timer_suspend NULL
-#define sa1100_timer_resume NULL
-#endif
-
-static struct clock_event_device ckevt_sa1100_osmr0 = {
- .name = "osmr0",
- .features = CLOCK_EVT_FEAT_ONESHOT,
- .rating = 200,
- .set_next_event = sa1100_osmr0_set_next_event,
- .set_mode = sa1100_osmr0_set_mode,
- .suspend = sa1100_timer_suspend,
- .resume = sa1100_timer_resume,
-};
-
-static struct irqaction sa1100_timer_irq = {
- .name = "ost0",
- .flags = IRQF_TIMER | IRQF_IRQPOLL,
- .handler = sa1100_ost0_interrupt,
- .dev_id = &ckevt_sa1100_osmr0,
-};
-
-void __init sa1100_timer_init(void)
-{
- writel_relaxed(0, OIER);
- writel_relaxed(OSSR_M0 | OSSR_M1 | OSSR_M2 | OSSR_M3, OSSR);
-
- sched_clock_register(sa1100_read_sched_clock, 32, 3686400);
-
- ckevt_sa1100_osmr0.cpumask = cpumask_of(0);
-
- setup_irq(IRQ_OST0, &sa1100_timer_irq);
-
- clocksource_mmio_init(OSCR, "oscr", SA1100_CLOCK_FREQ, 200, 32,
- clocksource_mmio_readl_up);
- clockevents_config_and_register(&ckevt_sa1100_osmr0, 3686400,
- MIN_OSCR_DELTA * 2, 0x7fffffff);
-}
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig
index 1b4fafe524ff..2f36c85eec4b 100644
--- a/arch/arm/mach-shmobile/Kconfig
+++ b/arch/arm/mach-shmobile/Kconfig
@@ -7,6 +7,7 @@ config PM_RCAR
config PM_RMOBILE
bool
+ select PM_GENERIC_DOMAINS
config ARCH_RCAR_GEN1
bool
@@ -23,7 +24,7 @@ config ARCH_RCAR_GEN2
config ARCH_RMOBILE
bool
- select PM_RMOBILE if PM && !ARCH_SHMOBILE_MULTI
+ select PM_RMOBILE if PM
select SYS_SUPPORTS_SH_CMT
select SYS_SUPPORTS_SH_TMU
@@ -51,6 +52,11 @@ config ARCH_R7S72100
bool "RZ/A1H (R7S72100)"
select SYS_SUPPORTS_SH_MTU2
+config ARCH_R8A73A4
+ bool "R-Mobile APE6 (R8A73A40)"
+ select ARCH_RMOBILE
+ select RENESAS_IRQC
+
config ARCH_R8A7740
bool "R-Mobile A1 (R8A77400)"
select ARCH_RMOBILE
@@ -74,11 +80,6 @@ config ARCH_R8A7794
comment "Renesas ARM SoCs Board Type"
-config MACH_LAGER
- bool "Lager board"
- depends on ARCH_R8A7790
- select MICREL_PHY if SH_ETH
-
config MACH_MARZEN
bool "MARZEN board"
depends on ARCH_R8A7779
@@ -133,14 +134,6 @@ config ARCH_R8A7779
select ARCH_WANT_OPTIONAL_GPIOLIB
select ARM_GIC
-config ARCH_R8A7790
- bool "R-Car H2 (R8A77900)"
- select ARCH_RCAR_GEN2
- select ARCH_WANT_OPTIONAL_GPIOLIB
- select ARM_GIC
- select MIGHT_HAVE_PCI
- select ARCH_DMA_ADDR_T_64BIT if ARM_LPAE
-
comment "Renesas ARM SoCs Board Type"
config MACH_APE6EVM
@@ -208,13 +201,6 @@ config MACH_MARZEN
select REGULATOR_FIXED_VOLTAGE if REGULATOR
select USE_OF
-config MACH_LAGER
- bool "Lager board"
- depends on ARCH_R8A7790
- select USE_OF
- select MICREL_PHY if SH_ETH
- select SND_SOC_AK4642 if SND_SIMPLE_CARD
-
config MACH_KZM9G
bool "KZM-A9-GT board"
depends on ARCH_SH73A0
diff --git a/arch/arm/mach-shmobile/Makefile b/arch/arm/mach-shmobile/Makefile
index b55cac0e5b2b..d53996e6da97 100644
--- a/arch/arm/mach-shmobile/Makefile
+++ b/arch/arm/mach-shmobile/Makefile
@@ -27,7 +27,6 @@ obj-$(CONFIG_ARCH_R8A73A4) += clock-r8a73a4.o
obj-$(CONFIG_ARCH_R8A7740) += clock-r8a7740.o
obj-$(CONFIG_ARCH_R8A7778) += clock-r8a7778.o
obj-$(CONFIG_ARCH_R8A7779) += clock-r8a7779.o
-obj-$(CONFIG_ARCH_R8A7790) += clock-r8a7790.o
endif
# CPU reset vector handling objects
@@ -57,7 +56,6 @@ obj-$(CONFIG_ARCH_SH7372) += entry-intc.o sleep-sh7372.o
# Board objects
ifdef CONFIG_ARCH_SHMOBILE_MULTI
-obj-$(CONFIG_MACH_LAGER) += board-lager-reference.o
obj-$(CONFIG_MACH_MARZEN) += board-marzen-reference.o
else
obj-$(CONFIG_MACH_APE6EVM) += board-ape6evm.o
@@ -66,7 +64,6 @@ obj-$(CONFIG_MACH_MACKEREL) += board-mackerel.o
obj-$(CONFIG_MACH_BOCKW) += board-bockw.o
obj-$(CONFIG_MACH_BOCKW_REFERENCE) += board-bockw-reference.o
obj-$(CONFIG_MACH_MARZEN) += board-marzen.o
-obj-$(CONFIG_MACH_LAGER) += board-lager.o
obj-$(CONFIG_MACH_ARMADILLO800EVA) += board-armadillo800eva.o
obj-$(CONFIG_MACH_KZM9G) += board-kzm9g.o
obj-$(CONFIG_MACH_KZM9G_REFERENCE) += board-kzm9g-reference.o
diff --git a/arch/arm/mach-shmobile/Makefile.boot b/arch/arm/mach-shmobile/Makefile.boot
index 57d00ed6ec0c..02532bea5300 100644
--- a/arch/arm/mach-shmobile/Makefile.boot
+++ b/arch/arm/mach-shmobile/Makefile.boot
@@ -7,7 +7,6 @@ loadaddr-$(CONFIG_MACH_BOCKW) += 0x60008000
loadaddr-$(CONFIG_MACH_BOCKW_REFERENCE) += 0x60008000
loadaddr-$(CONFIG_MACH_KZM9G) += 0x41008000
loadaddr-$(CONFIG_MACH_KZM9G_REFERENCE) += 0x41008000
-loadaddr-$(CONFIG_MACH_LAGER) += 0x40008000
loadaddr-$(CONFIG_MACH_MACKEREL) += 0x40008000
loadaddr-$(CONFIG_MACH_MARZEN) += 0x60008000
diff --git a/arch/arm/mach-shmobile/board-ape6evm.c b/arch/arm/mach-shmobile/board-ape6evm.c
index 66f67816a844..444f22d370f0 100644
--- a/arch/arm/mach-shmobile/board-ape6evm.c
+++ b/arch/arm/mach-shmobile/board-ape6evm.c
@@ -18,6 +18,8 @@
#include <linux/gpio_keys.h>
#include <linux/input.h>
#include <linux/interrupt.h>
+#include <linux/irqchip.h>
+#include <linux/irqchip/arm-gic.h>
#include <linux/kernel.h>
#include <linux/mfd/tmio.h>
#include <linux/mmc/host.h>
@@ -273,6 +275,22 @@ static void __init ape6evm_add_standard_devices(void)
sizeof(ape6evm_leds_pdata));
}
+static void __init ape6evm_legacy_init_time(void)
+{
+ /* Do not invoke DT-based timers via clocksource_of_init() */
+}
+
+static void __init ape6evm_legacy_init_irq(void)
+{
+ void __iomem *gic_dist_base = ioremap_nocache(0xf1001000, 0x1000);
+ void __iomem *gic_cpu_base = ioremap_nocache(0xf1002000, 0x1000);
+
+ gic_init(0, 29, gic_dist_base, gic_cpu_base);
+
+ /* Do not invoke DT-based interrupt code via irqchip_init() */
+}
+
+
static const char *ape6evm_boards_compat_dt[] __initdata = {
"renesas,ape6evm",
NULL,
@@ -280,7 +298,9 @@ static const char *ape6evm_boards_compat_dt[] __initdata = {
DT_MACHINE_START(APE6EVM_DT, "ape6evm")
.init_early = shmobile_init_delay,
+ .init_irq = ape6evm_legacy_init_irq,
.init_machine = ape6evm_add_standard_devices,
.init_late = shmobile_init_late,
.dt_compat = ape6evm_boards_compat_dt,
+ .init_time = ape6evm_legacy_init_time,
MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-lager-reference.c b/arch/arm/mach-shmobile/board-lager-reference.c
deleted file mode 100644
index fa06bdba61df..000000000000
--- a/arch/arm/mach-shmobile/board-lager-reference.c
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Lager board support - Reference DT implementation
- *
- * Copyright (C) 2013 Renesas Solutions Corp.
- * Copyright (C) 2013 Simon Horman
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/init.h>
-#include <linux/of_platform.h>
-
-#include <asm/mach/arch.h>
-
-#include "common.h"
-#include "r8a7790.h"
-#include "rcar-gen2.h"
-
-static const char *lager_boards_compat_dt[] __initdata = {
- "renesas,lager",
- "renesas,lager-reference",
- NULL,
-};
-
-DT_MACHINE_START(LAGER_DT, "lager")
- .smp = smp_ops(r8a7790_smp_ops),
- .init_early = shmobile_init_delay,
- .init_time = rcar_gen2_timer_init,
- .init_late = shmobile_init_late,
- .reserve = rcar_gen2_reserve,
- .dt_compat = lager_boards_compat_dt,
-MACHINE_END
diff --git a/arch/arm/mach-shmobile/board-lager.c b/arch/arm/mach-shmobile/board-lager.c
deleted file mode 100644
index f8197eb6e566..000000000000
--- a/arch/arm/mach-shmobile/board-lager.c
+++ /dev/null
@@ -1,827 +0,0 @@
-/*
- * Lager board support
- *
- * Copyright (C) 2013-2014 Renesas Solutions Corp.
- * Copyright (C) 2013 Magnus Damm
- * Copyright (C) 2014 Cogent Embedded, Inc.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-
-#include <linux/gpio.h>
-#include <linux/gpio_keys.h>
-#include <linux/i2c.h>
-#include <linux/input.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/leds.h>
-#include <linux/mfd/tmio.h>
-#include <linux/mmc/host.h>
-#include <linux/mmc/sh_mmcif.h>
-#include <linux/mmc/sh_mobile_sdhi.h>
-#include <linux/mtd/partitions.h>
-#include <linux/mtd/mtd.h>
-#include <linux/pinctrl/machine.h>
-#include <linux/platform_data/camera-rcar.h>
-#include <linux/platform_data/gpio-rcar.h>
-#include <linux/platform_data/usb-rcar-gen2-phy.h>
-#include <linux/platform_device.h>
-#include <linux/phy.h>
-#include <linux/regulator/driver.h>
-#include <linux/regulator/fixed.h>
-#include <linux/regulator/gpio-regulator.h>
-#include <linux/regulator/machine.h>
-#include <linux/sh_eth.h>
-#include <linux/spi/flash.h>
-#include <linux/spi/rspi.h>
-#include <linux/spi/spi.h>
-#include <linux/usb/phy.h>
-#include <linux/usb/renesas_usbhs.h>
-
-#include <media/soc_camera.h>
-#include <asm/mach-types.h>
-#include <asm/mach/arch.h>
-#include <sound/rcar_snd.h>
-#include <sound/simple_card.h>
-
-#include "common.h"
-#include "irqs.h"
-#include "r8a7790.h"
-#include "rcar-gen2.h"
-
-/*
- * SSI-AK4643
- *
- * SW1: 1: AK4643
- * 2: CN22
- * 3: ADV7511
- *
- * this command is required when playback.
- *
- * # amixer set "LINEOUT Mixer DACL" on
- */
-
-/*
- * SDHI0 (CN8)
- *
- * JP3: pin1
- * SW20: pin1
-
- * GP5_24: 1: VDD 3.3V (defult)
- * 0: VDD 0.0V
- * GP5_29: 1: VccQ 3.3V (defult)
- * 0: VccQ 1.8V
- *
- */
-
-/* LEDS */
-static struct gpio_led lager_leds[] = {
- {
- .name = "led8",
- .gpio = RCAR_GP_PIN(5, 17),
- .default_state = LEDS_GPIO_DEFSTATE_ON,
- }, {
- .name = "led7",
- .gpio = RCAR_GP_PIN(4, 23),
- .default_state = LEDS_GPIO_DEFSTATE_ON,
- }, {
- .name = "led6",
- .gpio = RCAR_GP_PIN(4, 22),
- .default_state = LEDS_GPIO_DEFSTATE_ON,
- },
-};
-
-static const struct gpio_led_platform_data lager_leds_pdata __initconst = {
- .leds = lager_leds,
- .num_leds = ARRAY_SIZE(lager_leds),
-};
-
-/* GPIO KEY */
-#define GPIO_KEY(c, g, d, ...) \
- { .code = c, .gpio = g, .desc = d, .active_low = 1, \
- .wakeup = 1, .debounce_interval = 20 }
-
-static struct gpio_keys_button gpio_buttons[] = {
- GPIO_KEY(KEY_4, RCAR_GP_PIN(1, 28), "SW2-pin4"),
- GPIO_KEY(KEY_3, RCAR_GP_PIN(1, 26), "SW2-pin3"),
- GPIO_KEY(KEY_2, RCAR_GP_PIN(1, 24), "SW2-pin2"),
- GPIO_KEY(KEY_1, RCAR_GP_PIN(1, 14), "SW2-pin1"),
-};
-
-static const struct gpio_keys_platform_data lager_keys_pdata __initconst = {
- .buttons = gpio_buttons,
- .nbuttons = ARRAY_SIZE(gpio_buttons),
-};
-
-/* Fixed 3.3V regulator to be used by MMCIF */
-static struct regulator_consumer_supply fixed3v3_power_consumers[] =
-{
- REGULATOR_SUPPLY("vmmc", "sh_mmcif.1"),
-};
-
-/*
- * SDHI regulator macro
- *
- ** FIXME**
- * Lager board vqmmc is provided via DA9063 PMIC chip,
- * and we should use ${LINK}/drivers/mfd/da9063-* driver for it.
- * but, it doesn't have regulator support at this point.
- * It uses gpio-regulator for vqmmc as quick-hack.
- */
-#define SDHI_REGULATOR(idx, vdd_pin, vccq_pin) \
-static struct regulator_consumer_supply vcc_sdhi##idx##_consumer = \
- REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi." #idx); \
- \
-static struct regulator_init_data vcc_sdhi##idx##_init_data = { \
- .constraints = { \
- .valid_ops_mask = REGULATOR_CHANGE_STATUS, \
- }, \
- .consumer_supplies = &vcc_sdhi##idx##_consumer, \
- .num_consumer_supplies = 1, \
-}; \
- \
-static const struct fixed_voltage_config vcc_sdhi##idx##_info __initconst = {\
- .supply_name = "SDHI" #idx "Vcc", \
- .microvolts = 3300000, \
- .gpio = vdd_pin, \
- .enable_high = 1, \
- .init_data = &vcc_sdhi##idx##_init_data, \
-}; \
- \
-static struct regulator_consumer_supply vccq_sdhi##idx##_consumer = \
- REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi." #idx); \
- \
-static struct regulator_init_data vccq_sdhi##idx##_init_data = { \
- .constraints = { \
- .input_uV = 3300000, \
- .min_uV = 1800000, \
- .max_uV = 3300000, \
- .valid_ops_mask = REGULATOR_CHANGE_VOLTAGE | \
- REGULATOR_CHANGE_STATUS, \
- }, \
- .consumer_supplies = &vccq_sdhi##idx##_consumer, \
- .num_consumer_supplies = 1, \
-}; \
- \
-static struct gpio vccq_sdhi##idx##_gpio = \
- { vccq_pin, GPIOF_OUT_INIT_HIGH, "vccq-sdhi" #idx }; \
- \
-static struct gpio_regulator_state vccq_sdhi##idx##_states[] = { \
- { .value = 1800000, .gpios = 0 }, \
- { .value = 3300000, .gpios = 1 }, \
-}; \
- \
-static const struct gpio_regulator_config vccq_sdhi##idx##_info __initconst = {\
- .supply_name = "vqmmc", \
- .gpios = &vccq_sdhi##idx##_gpio, \
- .nr_gpios = 1, \
- .states = vccq_sdhi##idx##_states, \
- .nr_states = ARRAY_SIZE(vccq_sdhi##idx##_states), \
- .type = REGULATOR_VOLTAGE, \
- .init_data = &vccq_sdhi##idx##_init_data, \
-};
-
-SDHI_REGULATOR(0, RCAR_GP_PIN(5, 24), RCAR_GP_PIN(5, 29));
-SDHI_REGULATOR(2, RCAR_GP_PIN(5, 25), RCAR_GP_PIN(5, 30));
-
-/* MMCIF */
-static const struct sh_mmcif_plat_data mmcif1_pdata __initconst = {
- .caps = MMC_CAP_8_BIT_DATA | MMC_CAP_NONREMOVABLE,
- .clk_ctrl2_present = true,
- .ccs_unsupported = true,
-};
-
-static const struct resource mmcif1_resources[] __initconst = {
- DEFINE_RES_MEM(0xee220000, 0x80),
- DEFINE_RES_IRQ(gic_spi(170)),
-};
-
-/* Ether */
-static const struct sh_eth_plat_data ether_pdata __initconst = {
- .phy = 0x1,
- .phy_irq = irq_pin(0),
- .edmac_endian = EDMAC_LITTLE_ENDIAN,
- .phy_interface = PHY_INTERFACE_MODE_RMII,
- .ether_link_active_low = 1,
-};
-
-static const struct resource ether_resources[] __initconst = {
- DEFINE_RES_MEM(0xee700000, 0x400),
- DEFINE_RES_IRQ(gic_spi(162)),
-};
-
-static const struct platform_device_info ether_info __initconst = {
- .name = "r8a7790-ether",
- .id = -1,
- .res = ether_resources,
- .num_res = ARRAY_SIZE(ether_resources),
- .data = &ether_pdata,
- .size_data = sizeof(ether_pdata),
- .dma_mask = DMA_BIT_MASK(32),
-};
-
-/* SPI Flash memory (Spansion S25FL512SAGMFIG11 64Mb) */
-static struct mtd_partition spi_flash_part[] = {
- /* Reserved for user loader program, read-only */
- {
- .name = "loader",
- .offset = 0,
- .size = SZ_256K,
- .mask_flags = MTD_WRITEABLE,
- },
- /* Reserved for user program, read-only */
- {
- .name = "user",
- .offset = MTDPART_OFS_APPEND,
- .size = SZ_4M,
- .mask_flags = MTD_WRITEABLE,
- },
- /* All else is writable (e.g. JFFS2) */
- {
- .name = "flash",
- .offset = MTDPART_OFS_APPEND,
- .size = MTDPART_SIZ_FULL,
- .mask_flags = 0,
- },
-};
-
-static const struct flash_platform_data spi_flash_data = {
- .name = "m25p80",
- .parts = spi_flash_part,
- .nr_parts = ARRAY_SIZE(spi_flash_part),
- .type = "s25fl512s",
-};
-
-static const struct rspi_plat_data qspi_pdata __initconst = {
- .num_chipselect = 1,
-};
-
-static const struct spi_board_info spi_info[] __initconst = {
- {
- .modalias = "m25p80",
- .platform_data = &spi_flash_data,
- .mode = SPI_MODE_0 | SPI_TX_QUAD | SPI_RX_QUAD,
- .max_speed_hz = 30000000,
- .bus_num = 0,
- .chip_select = 0,
- },
-};
-
-/* QSPI resource */
-static const struct resource qspi_resources[] __initconst = {
- DEFINE_RES_MEM(0xe6b10000, 0x1000),
- DEFINE_RES_IRQ_NAMED(gic_spi(184), "mux"),
-};
-
-/* VIN */
-static const struct resource vin_resources[] __initconst = {
- /* VIN0 */
- DEFINE_RES_MEM(0xe6ef0000, 0x1000),
- DEFINE_RES_IRQ(gic_spi(188)),
- /* VIN1 */
- DEFINE_RES_MEM(0xe6ef1000, 0x1000),
- DEFINE_RES_IRQ(gic_spi(189)),
-};
-
-static void __init lager_add_vin_device(unsigned idx,
- struct rcar_vin_platform_data *pdata)
-{
- struct platform_device_info vin_info = {
- .name = "r8a7790-vin",
- .id = idx,
- .res = &vin_resources[idx * 2],
- .num_res = 2,
- .dma_mask = DMA_BIT_MASK(32),
- .data = pdata,
- .size_data = sizeof(*pdata),
- };
-
- BUG_ON(idx > 1);
-
- platform_device_register_full(&vin_info);
-}
-
-#define LAGER_CAMERA(idx, name, addr, pdata, flag) \
-static struct i2c_board_info i2c_cam##idx##_device = { \
- I2C_BOARD_INFO(name, addr), \
-}; \
- \
-static struct rcar_vin_platform_data vin##idx##_pdata = { \
- .flags = flag, \
-}; \
- \
-static struct soc_camera_link cam##idx##_link = { \
- .bus_id = idx, \
- .board_info = &i2c_cam##idx##_device, \
- .i2c_adapter_id = 2, \
- .module_name = name, \
- .priv = pdata, \
-}
-
-/* Camera 0 is not currently supported due to adv7612 support missing */
-LAGER_CAMERA(1, "adv7180", 0x20, NULL, RCAR_VIN_BT656);
-
-static void __init lager_add_camera1_device(void)
-{
- platform_device_register_data(NULL, "soc-camera-pdrv", 1,
- &cam1_link, sizeof(cam1_link));
- lager_add_vin_device(1, &vin1_pdata);
-}
-
-/* SATA1 */
-static const struct resource sata1_resources[] __initconst = {
- DEFINE_RES_MEM(0xee500000, 0x2000),
- DEFINE_RES_IRQ(gic_spi(106)),
-};
-
-static const struct platform_device_info sata1_info __initconst = {
- .name = "sata-r8a7790",
- .id = 1,
- .res = sata1_resources,
- .num_res = ARRAY_SIZE(sata1_resources),
- .dma_mask = DMA_BIT_MASK(32),
-};
-
-/* USBHS */
-static const struct resource usbhs_resources[] __initconst = {
- DEFINE_RES_MEM(0xe6590000, 0x100),
- DEFINE_RES_IRQ(gic_spi(107)),
-};
-
-struct usbhs_private {
- struct renesas_usbhs_platform_info info;
- struct usb_phy *phy;
-};
-
-#define usbhs_get_priv(pdev) \
- container_of(renesas_usbhs_get_info(pdev), struct usbhs_private, info)
-
-static int usbhs_power_ctrl(struct platform_device *pdev,
- void __iomem *base, int enable)
-{
- struct usbhs_private *priv = usbhs_get_priv(pdev);
-
- if (!priv->phy)
- return -ENODEV;
-
- if (enable) {
- int retval = usb_phy_init(priv->phy);
-
- if (!retval)
- retval = usb_phy_set_suspend(priv->phy, 0);
- return retval;
- }
-
- usb_phy_set_suspend(priv->phy, 1);
- usb_phy_shutdown(priv->phy);
- return 0;
-}
-
-static int usbhs_hardware_init(struct platform_device *pdev)
-{
- struct usbhs_private *priv = usbhs_get_priv(pdev);
- struct usb_phy *phy;
- int ret;
-
- /* USB0 Function - use PWEN as GPIO input to detect DIP Switch SW5
- * setting to avoid VBUS short circuit due to wrong cable.
- * PWEN should be pulled up high if USB Function is selected by SW5
- */
- gpio_request_one(RCAR_GP_PIN(5, 18), GPIOF_IN, NULL); /* USB0_PWEN */
- if (!gpio_get_value(RCAR_GP_PIN(5, 18))) {
- pr_warn("Error: USB Function not selected - check SW5 + SW6\n");
- ret = -ENOTSUPP;
- goto error;
- }
-
- phy = usb_get_phy_dev(&pdev->dev, 0);
- if (IS_ERR(phy)) {
- ret = PTR_ERR(phy);
- goto error;
- }
-
- priv->phy = phy;
- return 0;
- error:
- gpio_free(RCAR_GP_PIN(5, 18));
- return ret;
-}
-
-static int usbhs_hardware_exit(struct platform_device *pdev)
-{
- struct usbhs_private *priv = usbhs_get_priv(pdev);
-
- if (!priv->phy)
- return 0;
-
- usb_put_phy(priv->phy);
- priv->phy = NULL;
-
- gpio_free(RCAR_GP_PIN(5, 18));
- return 0;
-}
-
-static int usbhs_get_id(struct platform_device *pdev)
-{
- return USBHS_GADGET;
-}
-
-static u32 lager_usbhs_pipe_type[] = {
- 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_priv __initdata = {
- .info = {
- .platform_callback = {
- .power_ctrl = usbhs_power_ctrl,
- .hardware_init = usbhs_hardware_init,
- .hardware_exit = usbhs_hardware_exit,
- .get_id = usbhs_get_id,
- },
- .driver_param = {
- .buswait_bwait = 4,
- .pipe_type = lager_usbhs_pipe_type,
- .pipe_size = ARRAY_SIZE(lager_usbhs_pipe_type),
- },
- }
-};
-
-static void __init lager_register_usbhs(void)
-{
- usb_bind_phy("renesas_usbhs", 0, "usb_phy_rcar_gen2");
- platform_device_register_resndata(NULL,
- "renesas_usbhs", -1,
- usbhs_resources,
- ARRAY_SIZE(usbhs_resources),
- &usbhs_priv.info,
- sizeof(usbhs_priv.info));
-}
-
-/* USBHS PHY */
-static const struct rcar_gen2_phy_platform_data usbhs_phy_pdata __initconst = {
- .chan0_pci = 0, /* Channel 0 is USBHS */
- .chan2_pci = 1, /* Channel 2 is PCI USB */
-};
-
-static const struct resource usbhs_phy_resources[] __initconst = {
- DEFINE_RES_MEM(0xe6590100, 0x100),
-};
-
-/* I2C */
-static struct i2c_board_info i2c2_devices[] = {
- {
- I2C_BOARD_INFO("ak4643", 0x12),
- }
-};
-
-/* Sound */
-static struct resource rsnd_resources[] __initdata = {
- [RSND_GEN2_SCU] = DEFINE_RES_MEM(0xec500000, 0x1000),
- [RSND_GEN2_ADG] = DEFINE_RES_MEM(0xec5a0000, 0x100),
- [RSND_GEN2_SSIU] = DEFINE_RES_MEM(0xec540000, 0x1000),
- [RSND_GEN2_SSI] = DEFINE_RES_MEM(0xec541000, 0x1280),
-};
-
-static struct rsnd_ssi_platform_info rsnd_ssi[] = {
- RSND_SSI(0, gic_spi(370), 0),
- RSND_SSI(0, gic_spi(371), RSND_SSI_CLK_PIN_SHARE),
-};
-
-static struct rsnd_src_platform_info rsnd_src[2] = {
- /* no member at this point */
-};
-
-static struct rsnd_dai_platform_info rsnd_dai = {
- .playback = { .ssi = &rsnd_ssi[0], },
- .capture = { .ssi = &rsnd_ssi[1], },
-};
-
-static struct rcar_snd_info rsnd_info = {
- .flags = RSND_GEN2,
- .ssi_info = rsnd_ssi,
- .ssi_info_nr = ARRAY_SIZE(rsnd_ssi),
- .src_info = rsnd_src,
- .src_info_nr = ARRAY_SIZE(rsnd_src),
- .dai_info = &rsnd_dai,
- .dai_info_nr = 1,
-};
-
-static struct asoc_simple_card_info rsnd_card_info = {
- .name = "AK4643",
- .card = "SSI01-AK4643",
- .codec = "ak4642-codec.2-0012",
- .platform = "rcar_sound",
- .daifmt = SND_SOC_DAIFMT_LEFT_J | SND_SOC_DAIFMT_CBM_CFM,
- .cpu_dai = {
- .name = "rcar_sound",
- },
- .codec_dai = {
- .name = "ak4642-hifi",
- .sysclk = 11289600,
- },
-};
-
-static void __init lager_add_rsnd_device(void)
-{
- struct platform_device_info cardinfo = {
- .name = "asoc-simple-card",
- .id = -1,
- .data = &rsnd_card_info,
- .size_data = sizeof(struct asoc_simple_card_info),
- .dma_mask = DMA_BIT_MASK(32),
- };
-
- i2c_register_board_info(2, i2c2_devices,
- ARRAY_SIZE(i2c2_devices));
-
- platform_device_register_resndata(
- NULL, "rcar_sound", -1,
- rsnd_resources, ARRAY_SIZE(rsnd_resources),
- &rsnd_info, sizeof(rsnd_info));
-
- platform_device_register_full(&cardinfo);
-}
-
-/* SDHI0 */
-static struct sh_mobile_sdhi_info sdhi0_info __initdata = {
- .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
- MMC_CAP_POWER_OFF_CARD,
- .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT |
- TMIO_MMC_WRPROTECT_DISABLE,
-};
-
-static struct resource sdhi0_resources[] __initdata = {
- DEFINE_RES_MEM(0xee100000, 0x200),
- DEFINE_RES_IRQ(gic_spi(165)),
-};
-
-/* SDHI2 */
-static struct sh_mobile_sdhi_info sdhi2_info __initdata = {
- .tmio_caps = MMC_CAP_SD_HIGHSPEED | MMC_CAP_SDIO_IRQ |
- MMC_CAP_POWER_OFF_CARD,
- .tmio_flags = TMIO_MMC_HAS_IDLE_WAIT |
- TMIO_MMC_WRPROTECT_DISABLE,
-};
-
-static struct resource sdhi2_resources[] __initdata = {
- DEFINE_RES_MEM(0xee140000, 0x100),
- DEFINE_RES_IRQ(gic_spi(167)),
-};
-
-/* Internal PCI1 */
-static const struct resource pci1_resources[] __initconst = {
- DEFINE_RES_MEM(0xee0b0000, 0x10000), /* CFG */
- DEFINE_RES_MEM(0xee0a0000, 0x10000), /* MEM */
- DEFINE_RES_IRQ(gic_spi(112)),
-};
-
-static const struct platform_device_info pci1_info __initconst = {
- .name = "pci-rcar-gen2",
- .id = 1,
- .res = pci1_resources,
- .num_res = ARRAY_SIZE(pci1_resources),
- .dma_mask = DMA_BIT_MASK(32),
-};
-
-static void __init lager_add_usb1_device(void)
-{
- platform_device_register_full(&pci1_info);
-}
-
-/* Internal PCI2 */
-static const struct resource pci2_resources[] __initconst = {
- DEFINE_RES_MEM(0xee0d0000, 0x10000), /* CFG */
- DEFINE_RES_MEM(0xee0c0000, 0x10000), /* MEM */
- DEFINE_RES_IRQ(gic_spi(113)),
-};
-
-static const struct platform_device_info pci2_info __initconst = {
- .name = "pci-rcar-gen2",
- .id = 2,
- .res = pci2_resources,
- .num_res = ARRAY_SIZE(pci2_resources),
- .dma_mask = DMA_BIT_MASK(32),
-};
-
-static void __init lager_add_usb2_device(void)
-{
- platform_device_register_full(&pci2_info);
-}
-
-static const struct pinctrl_map lager_pinctrl_map[] = {
- /* DU (CN10: ARGB0, CN13: LVDS) */
- PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790",
- "du_rgb666", "du"),
- PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790",
- "du_sync_1", "du"),
- PIN_MAP_MUX_GROUP_DEFAULT("rcar-du-r8a7790", "pfc-r8a7790",
- "du_clk_out_0", "du"),
- /* I2C2 */
- PIN_MAP_MUX_GROUP_DEFAULT("i2c-rcar.2", "pfc-r8a7790",
- "i2c2", "i2c2"),
- /* QSPI */
- PIN_MAP_MUX_GROUP_DEFAULT("qspi.0", "pfc-r8a7790",
- "qspi_ctrl", "qspi"),
- PIN_MAP_MUX_GROUP_DEFAULT("qspi.0", "pfc-r8a7790",
- "qspi_data4", "qspi"),
- /* SCIF0 (CN19: DEBUG SERIAL0) */
- PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.6", "pfc-r8a7790",
- "scif0_data", "scif0"),
- /* SCIF1 (CN20: DEBUG SERIAL1) */
- PIN_MAP_MUX_GROUP_DEFAULT("sh-sci.7", "pfc-r8a7790",
- "scif1_data", "scif1"),
- /* SDHI0 */
- PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7790",
- "sdhi0_data4", "sdhi0"),
- PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7790",
- "sdhi0_ctrl", "sdhi0"),
- PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.0", "pfc-r8a7790",
- "sdhi0_cd", "sdhi0"),
- /* SDHI2 */
- PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7790",
- "sdhi2_data4", "sdhi2"),
- PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7790",
- "sdhi2_ctrl", "sdhi2"),
- PIN_MAP_MUX_GROUP_DEFAULT("sh_mobile_sdhi.2", "pfc-r8a7790",
- "sdhi2_cd", "sdhi2"),
- /* SSI (CN17: sound) */
- PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7790",
- "ssi0129_ctrl", "ssi"),
- PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7790",
- "ssi0_data", "ssi"),
- PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7790",
- "ssi1_data", "ssi"),
- PIN_MAP_MUX_GROUP_DEFAULT("rcar_sound", "pfc-r8a7790",
- "audio_clk_a", "audio_clk"),
- /* MMCIF1 */
- PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.1", "pfc-r8a7790",
- "mmc1_data8", "mmc1"),
- PIN_MAP_MUX_GROUP_DEFAULT("sh_mmcif.1", "pfc-r8a7790",
- "mmc1_ctrl", "mmc1"),
- /* Ether */
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-ether", "pfc-r8a7790",
- "eth_link", "eth"),
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-ether", "pfc-r8a7790",
- "eth_mdio", "eth"),
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-ether", "pfc-r8a7790",
- "eth_rmii", "eth"),
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-ether", "pfc-r8a7790",
- "intc_irq0", "intc"),
- /* VIN0 */
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790",
- "vin0_data24", "vin0"),
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790",
- "vin0_sync", "vin0"),
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790",
- "vin0_field", "vin0"),
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790",
- "vin0_clkenb", "vin0"),
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.0", "pfc-r8a7790",
- "vin0_clk", "vin0"),
- /* VIN1 */
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.1", "pfc-r8a7790",
- "vin1_data8", "vin1"),
- PIN_MAP_MUX_GROUP_DEFAULT("r8a7790-vin.1", "pfc-r8a7790",
- "vin1_clk", "vin1"),
- /* USB0 */
- PIN_MAP_MUX_GROUP_DEFAULT("renesas_usbhs", "pfc-r8a7790",
- "usb0_ovc_vbus", "usb0"),
- /* USB1 */
- PIN_MAP_MUX_GROUP_DEFAULT("pci-rcar-gen2.1", "pfc-r8a7790",
- "usb1", "usb1"),
- /* USB2 */
- PIN_MAP_MUX_GROUP_DEFAULT("pci-rcar-gen2.2", "pfc-r8a7790",
- "usb2", "usb2"),
-};
-
-static void __init lager_add_standard_devices(void)
-{
- int fixed_regulator_idx = 0;
- int gpio_regulator_idx = 0;
-
- r8a7790_clock_init();
-
- pinctrl_register_mappings(lager_pinctrl_map,
- ARRAY_SIZE(lager_pinctrl_map));
- r8a7790_pinmux_init();
-
- r8a7790_add_standard_devices();
- platform_device_register_data(NULL, "leds-gpio", -1,
- &lager_leds_pdata,
- sizeof(lager_leds_pdata));
- platform_device_register_data(NULL, "gpio-keys", -1,
- &lager_keys_pdata,
- sizeof(lager_keys_pdata));
- regulator_register_always_on(fixed_regulator_idx++,
- "fixed-3.3V", fixed3v3_power_consumers,
- ARRAY_SIZE(fixed3v3_power_consumers), 3300000);
- platform_device_register_resndata(NULL, "sh_mmcif", 1,
- mmcif1_resources, ARRAY_SIZE(mmcif1_resources),
- &mmcif1_pdata, sizeof(mmcif1_pdata));
-
- platform_device_register_full(&ether_info);
-
- platform_device_register_resndata(NULL, "qspi", 0,
- qspi_resources,
- ARRAY_SIZE(qspi_resources),
- &qspi_pdata, sizeof(qspi_pdata));
- spi_register_board_info(spi_info, ARRAY_SIZE(spi_info));
-
- platform_device_register_data(NULL, "reg-fixed-voltage", fixed_regulator_idx++,
- &vcc_sdhi0_info, sizeof(struct fixed_voltage_config));
- platform_device_register_data(NULL, "reg-fixed-voltage", fixed_regulator_idx++,
- &vcc_sdhi2_info, sizeof(struct fixed_voltage_config));
-
- platform_device_register_data(NULL, "gpio-regulator", gpio_regulator_idx++,
- &vccq_sdhi0_info, sizeof(struct gpio_regulator_config));
- platform_device_register_data(NULL, "gpio-regulator", gpio_regulator_idx++,
- &vccq_sdhi2_info, sizeof(struct gpio_regulator_config));
-
- lager_add_camera1_device();
-
- platform_device_register_full(&sata1_info);
-
- platform_device_register_resndata(NULL, "usb_phy_rcar_gen2",
- -1, usbhs_phy_resources,
- ARRAY_SIZE(usbhs_phy_resources),
- &usbhs_phy_pdata,
- sizeof(usbhs_phy_pdata));
- lager_register_usbhs();
- lager_add_usb1_device();
- lager_add_usb2_device();
-
- lager_add_rsnd_device();
-
- platform_device_register_resndata(NULL, "sh_mobile_sdhi", 0,
- sdhi0_resources, ARRAY_SIZE(sdhi0_resources),
- &sdhi0_info, sizeof(struct sh_mobile_sdhi_info));
- platform_device_register_resndata(NULL, "sh_mobile_sdhi", 2,
- sdhi2_resources, ARRAY_SIZE(sdhi2_resources),
- &sdhi2_info, sizeof(struct sh_mobile_sdhi_info));
-}
-
-/*
- * Ether LEDs on the Lager board are named LINK and ACTIVE which corresponds
- * to non-default 01 setting of the Micrel KSZ8041 PHY control register 1 bits
- * 14-15. We have to set them back to 01 from the default 00 value each time
- * the PHY is reset. It's also important because the PHY's LED0 signal is
- * connected to SoC's ETH_LINK signal and in the PHY's default mode it will
- * bounce on and off after each packet, which we apparently want to avoid.
- */
-static int lager_ksz8041_fixup(struct phy_device *phydev)
-{
- u16 phyctrl1 = phy_read(phydev, 0x1e);
-
- phyctrl1 &= ~0xc000;
- phyctrl1 |= 0x4000;
- return phy_write(phydev, 0x1e, phyctrl1);
-}
-
-static void __init lager_init(void)
-{
- lager_add_standard_devices();
-
- irq_set_irq_type(irq_pin(0), IRQ_TYPE_LEVEL_LOW);
-
- if (IS_ENABLED(CONFIG_PHYLIB))
- phy_register_fixup_for_id("r8a7790-ether-ff:01",
- lager_ksz8041_fixup);
-}
-
-static const char * const lager_boards_compat_dt[] __initconst = {
- "renesas,lager",
- NULL,
-};
-
-DT_MACHINE_START(LAGER_DT, "lager")
- .smp = smp_ops(r8a7790_smp_ops),
- .init_early = shmobile_init_delay,
- .init_time = rcar_gen2_timer_init,
- .init_machine = lager_init,
- .init_late = shmobile_init_late,
- .reserve = rcar_gen2_reserve,
- .dt_compat = lager_boards_compat_dt,
-MACHINE_END
diff --git a/arch/arm/mach-shmobile/clock-r8a7790.c b/arch/arm/mach-shmobile/clock-r8a7790.c
deleted file mode 100644
index f9bbc5f0a9a1..000000000000
--- a/arch/arm/mach-shmobile/clock-r8a7790.c
+++ /dev/null
@@ -1,459 +0,0 @@
-/*
- * r8a7790 clock framework support
- *
- * Copyright (C) 2013 Renesas Solutions Corp.
- * Copyright (C) 2013 Magnus Damm
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; version 2 of the License.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- */
-#include <linux/init.h>
-#include <linux/io.h>
-#include <linux/kernel.h>
-#include <linux/sh_clk.h>
-#include <linux/clkdev.h>
-
-#include "clock.h"
-#include "common.h"
-#include "r8a7790.h"
-#include "rcar-gen2.h"
-
-/*
- * MD EXTAL PLL0 PLL1 PLL3
- * 14 13 19 (MHz) *1 *1
- *---------------------------------------------------
- * 0 0 0 15 x 1 x172/2 x208/2 x106
- * 0 0 1 15 x 1 x172/2 x208/2 x88
- * 0 1 0 20 x 1 x130/2 x156/2 x80
- * 0 1 1 20 x 1 x130/2 x156/2 x66
- * 1 0 0 26 / 2 x200/2 x240/2 x122
- * 1 0 1 26 / 2 x200/2 x240/2 x102
- * 1 1 0 30 / 2 x172/2 x208/2 x106
- * 1 1 1 30 / 2 x172/2 x208/2 x88
- *
- * *1 : Table 7.6 indicates VCO ouput (PLLx = VCO/2)
- * see "p1 / 2" on R8A7790_CLOCK_ROOT() below
- */
-
-#define CPG_BASE 0xe6150000
-#define CPG_LEN 0x1000
-
-#define SMSTPCR1 0xe6150134
-#define SMSTPCR2 0xe6150138
-#define SMSTPCR3 0xe615013c
-#define SMSTPCR5 0xe6150144
-#define SMSTPCR7 0xe615014c
-#define SMSTPCR8 0xe6150990
-#define SMSTPCR9 0xe6150994
-#define SMSTPCR10 0xe6150998
-
-#define MSTPSR1 IOMEM(0xe6150038)
-#define MSTPSR2 IOMEM(0xe6150040)
-#define MSTPSR3 IOMEM(0xe6150048)
-#define MSTPSR5 IOMEM(0xe615003c)
-#define MSTPSR7 IOMEM(0xe61501c4)
-#define MSTPSR8 IOMEM(0xe61509a0)
-#define MSTPSR9 IOMEM(0xe61509a4)
-#define MSTPSR10 IOMEM(0xe61509a8)
-
-#define SDCKCR 0xE6150074
-#define SD2CKCR 0xE6150078
-#define SD3CKCR 0xE615026C
-#define MMC0CKCR 0xE6150240
-#define MMC1CKCR 0xE6150244
-#define SSPCKCR 0xE6150248
-#define SSPRSCKCR 0xE615024C
-
-static struct clk_mapping cpg_mapping = {
- .phys = CPG_BASE,
- .len = CPG_LEN,
-};
-
-static struct clk extal_clk = {
- /* .rate will be updated on r8a7790_clock_init() */
- .mapping = &cpg_mapping,
-};
-
-static struct sh_clk_ops followparent_clk_ops = {
- .recalc = followparent_recalc,
-};
-
-static struct clk main_clk = {
- /* .parent will be set r8a7790_clock_init */
- .ops = &followparent_clk_ops,
-};
-
-static struct clk audio_clk_a = {
-};
-
-static struct clk audio_clk_b = {
-};
-
-static struct clk audio_clk_c = {
-};
-
-/*
- * clock ratio of these clock will be updated
- * on r8a7790_clock_init()
- */
-SH_FIXED_RATIO_CLK_SET(pll1_clk, main_clk, 1, 1);
-SH_FIXED_RATIO_CLK_SET(pll3_clk, main_clk, 1, 1);
-SH_FIXED_RATIO_CLK_SET(lb_clk, pll1_clk, 1, 1);
-SH_FIXED_RATIO_CLK_SET(qspi_clk, pll1_clk, 1, 1);
-
-/* fixed ratio clock */
-SH_FIXED_RATIO_CLK_SET(extal_div2_clk, extal_clk, 1, 2);
-SH_FIXED_RATIO_CLK_SET(cp_clk, extal_clk, 1, 2);
-
-SH_FIXED_RATIO_CLK_SET(pll1_div2_clk, pll1_clk, 1, 2);
-SH_FIXED_RATIO_CLK_SET(zg_clk, pll1_clk, 1, 3);
-SH_FIXED_RATIO_CLK_SET(zx_clk, pll1_clk, 1, 3);
-SH_FIXED_RATIO_CLK_SET(zs_clk, pll1_clk, 1, 6);
-SH_FIXED_RATIO_CLK_SET(hp_clk, pll1_clk, 1, 12);
-SH_FIXED_RATIO_CLK_SET(i_clk, pll1_clk, 1, 2);
-SH_FIXED_RATIO_CLK_SET(b_clk, pll1_clk, 1, 12);
-SH_FIXED_RATIO_CLK_SET(p_clk, pll1_clk, 1, 24);
-SH_FIXED_RATIO_CLK_SET(cl_clk, pll1_clk, 1, 48);
-SH_FIXED_RATIO_CLK_SET(m2_clk, pll1_clk, 1, 8);
-SH_FIXED_RATIO_CLK_SET(imp_clk, pll1_clk, 1, 4);
-SH_FIXED_RATIO_CLK_SET(rclk_clk, pll1_clk, 1, (48 * 1024));
-SH_FIXED_RATIO_CLK_SET(oscclk_clk, pll1_clk, 1, (12 * 1024));
-
-SH_FIXED_RATIO_CLK_SET(zb3_clk, pll3_clk, 1, 4);
-SH_FIXED_RATIO_CLK_SET(zb3d2_clk, pll3_clk, 1, 8);
-SH_FIXED_RATIO_CLK_SET(ddr_clk, pll3_clk, 1, 8);
-SH_FIXED_RATIO_CLK_SET(mp_clk, pll1_div2_clk, 1, 15);
-
-static struct clk *main_clks[] = {
- &audio_clk_a,
- &audio_clk_b,
- &audio_clk_c,
- &extal_clk,
- &extal_div2_clk,
- &main_clk,
- &pll1_clk,
- &pll1_div2_clk,
- &pll3_clk,
- &lb_clk,
- &qspi_clk,
- &zg_clk,
- &zx_clk,
- &zs_clk,
- &hp_clk,
- &i_clk,
- &b_clk,
- &p_clk,
- &cl_clk,
- &m2_clk,
- &imp_clk,
- &rclk_clk,
- &oscclk_clk,
- &zb3_clk,
- &zb3d2_clk,
- &ddr_clk,
- &mp_clk,
- &cp_clk,
-};
-
-/* SDHI (DIV4) clock */
-static int divisors[] = { 2, 3, 4, 6, 8, 12, 16, 18, 24, 0, 36, 48, 10 };
-
-static struct clk_div_mult_table div4_div_mult_table = {
- .divisors = divisors,
- .nr_divisors = ARRAY_SIZE(divisors),
-};
-
-static struct clk_div4_table div4_table = {
- .div_mult_table = &div4_div_mult_table,
-};
-
-enum {
- DIV4_SDH, DIV4_SD0, DIV4_SD1, DIV4_NR
-};
-
-static struct clk div4_clks[DIV4_NR] = {
- [DIV4_SDH] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 8, 0x0dff, CLK_ENABLE_ON_INIT),
- [DIV4_SD0] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 4, 0x1df0, CLK_ENABLE_ON_INIT),
- [DIV4_SD1] = SH_CLK_DIV4(&pll1_clk, SDCKCR, 0, 0x1df0, CLK_ENABLE_ON_INIT),
-};
-
-/* DIV6 clocks */
-enum {
- DIV6_SD2, DIV6_SD3,
- DIV6_MMC0, DIV6_MMC1,
- DIV6_SSP, DIV6_SSPRS,
- DIV6_NR
-};
-
-static struct clk div6_clks[DIV6_NR] = {
- [DIV6_SD2] = SH_CLK_DIV6(&pll1_div2_clk, SD2CKCR, 0),
- [DIV6_SD3] = SH_CLK_DIV6(&pll1_div2_clk, SD3CKCR, 0),
- [DIV6_MMC0] = SH_CLK_DIV6(&pll1_div2_clk, MMC0CKCR, 0),
- [DIV6_MMC1] = SH_CLK_DIV6(&pll1_div2_clk, MMC1CKCR, 0),
- [DIV6_SSP] = SH_CLK_DIV6(&pll1_div2_clk, SSPCKCR, 0),
- [DIV6_SSPRS] = SH_CLK_DIV6(&pll1_div2_clk, SSPRSCKCR, 0),
-};
-
-/* MSTP */
-enum {
- MSTP1017, /* parent of SCU */
-
- MSTP1031, MSTP1030,
- MSTP1029, MSTP1028, MSTP1027, MSTP1026, MSTP1025, MSTP1024, MSTP1023, MSTP1022,
- MSTP1015, MSTP1014, MSTP1013, MSTP1012, MSTP1011, MSTP1010,
- MSTP1009, MSTP1008, MSTP1007, MSTP1006, MSTP1005,
- MSTP931, MSTP930, MSTP929, MSTP928,
- MSTP917,
- MSTP815, MSTP814,
- MSTP813,
- MSTP811, MSTP810, MSTP809, MSTP808,
- MSTP726, MSTP725, MSTP724, MSTP723, MSTP722, MSTP721, MSTP720,
- MSTP717, MSTP716,
- MSTP704, MSTP703,
- MSTP522,
- MSTP502, MSTP501,
- MSTP315, MSTP314, MSTP313, MSTP312, MSTP311, MSTP305, MSTP304,
- MSTP216, MSTP207, MSTP206, MSTP204, MSTP203, MSTP202,
- MSTP124,
- MSTP_NR
-};
-
-static struct clk mstp_clks[MSTP_NR] = {
- [MSTP1031] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 31, MSTPSR10, 0), /* SCU0 */
- [MSTP1030] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 30, MSTPSR10, 0), /* SCU1 */
- [MSTP1029] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 29, MSTPSR10, 0), /* SCU2 */
- [MSTP1028] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 28, MSTPSR10, 0), /* SCU3 */
- [MSTP1027] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 27, MSTPSR10, 0), /* SCU4 */
- [MSTP1026] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 26, MSTPSR10, 0), /* SCU5 */
- [MSTP1025] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 25, MSTPSR10, 0), /* SCU6 */
- [MSTP1024] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 24, MSTPSR10, 0), /* SCU7 */
- [MSTP1023] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 23, MSTPSR10, 0), /* SCU8 */
- [MSTP1022] = SH_CLK_MSTP32_STS(&mstp_clks[MSTP1017], SMSTPCR10, 22, MSTPSR10, 0), /* SCU9 */
- [MSTP1017] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 17, MSTPSR10, 0), /* SCU */
- [MSTP1015] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 15, MSTPSR10, 0), /* SSI0 */
- [MSTP1014] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 14, MSTPSR10, 0), /* SSI1 */
- [MSTP1013] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 13, MSTPSR10, 0), /* SSI2 */
- [MSTP1012] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 12, MSTPSR10, 0), /* SSI3 */
- [MSTP1011] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 11, MSTPSR10, 0), /* SSI4 */
- [MSTP1010] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 10, MSTPSR10, 0), /* SSI5 */
- [MSTP1009] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 9, MSTPSR10, 0), /* SSI6 */
- [MSTP1008] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 8, MSTPSR10, 0), /* SSI7 */
- [MSTP1007] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 7, MSTPSR10, 0), /* SSI8 */
- [MSTP1006] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 6, MSTPSR10, 0), /* SSI9 */
- [MSTP1005] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR10, 5, MSTPSR10, 0), /* SSI ALL */
- [MSTP931] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 31, MSTPSR9, 0), /* I2C0 */
- [MSTP930] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 30, MSTPSR9, 0), /* I2C1 */
- [MSTP929] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 29, MSTPSR9, 0), /* I2C2 */
- [MSTP928] = SH_CLK_MSTP32_STS(&hp_clk, SMSTPCR9, 28, MSTPSR9, 0), /* I2C3 */
- [MSTP917] = SH_CLK_MSTP32_STS(&qspi_clk, SMSTPCR9, 17, MSTPSR9, 0), /* QSPI */
- [MSTP815] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 15, MSTPSR8, 0), /* SATA0 */
- [MSTP814] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR8, 14, MSTPSR8, 0), /* SATA1 */
- [MSTP813] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR8, 13, MSTPSR8, 0), /* Ether */
- [MSTP811] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 11, MSTPSR8, 0), /* VIN0 */
- [MSTP810] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 10, MSTPSR8, 0), /* VIN1 */
- [MSTP809] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 9, MSTPSR8, 0), /* VIN2 */
- [MSTP808] = SH_CLK_MSTP32_STS(&zg_clk, SMSTPCR8, 8, MSTPSR8, 0), /* VIN3 */
- [MSTP726] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 26, MSTPSR7, 0), /* LVDS0 */
- [MSTP725] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 25, MSTPSR7, 0), /* LVDS1 */
- [MSTP724] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 24, MSTPSR7, 0), /* DU0 */
- [MSTP723] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 23, MSTPSR7, 0), /* DU1 */
- [MSTP722] = SH_CLK_MSTP32_STS(&zx_clk, SMSTPCR7, 22, MSTPSR7, 0), /* DU2 */
- [MSTP721] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 21, MSTPSR7, 0), /* SCIF0 */
- [MSTP720] = SH_CLK_MSTP32_STS(&p_clk, SMSTPCR7, 20, MSTPSR7, 0), /* SCIF1 */
- [MSTP717] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR7, 17, MSTPSR7, 0), /* HSCIF0 */
- [MSTP716] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR7, 16, MSTPSR7, 0), /* HSCIF1 */
- [MSTP704] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR7, 4, MSTPSR7, 0), /* HSUSB */
- [MSTP703] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR7, 3, MSTPSR7, 0), /* EHCI */
- [MSTP522] = SH_CLK_MSTP32_STS(&extal_clk, SMSTPCR5, 22, MSTPSR5, 0), /* Thermal */
- [MSTP502] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR5, 2, MSTPSR5, 0), /* Audio-DMAC low */
- [MSTP501] = SH_CLK_MSTP32_STS(&zs_clk, SMSTPCR5, 1, MSTPSR5, 0), /* Audio-DMAC hi */
- [MSTP315] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_MMC0], SMSTPCR3, 15, MSTPSR3, 0), /* MMC0 */
- [MSTP314] = SH_CLK_MSTP32_STS(&div4_clks[DIV4_SD0], SMSTPCR3, 14, MSTPSR3, 0), /* SDHI0 */
- [MSTP313] = SH_CLK_MSTP32_STS(&div4_clks[DIV4_SD1], SMSTPCR3, 13, MSTPSR3, 0), /* SDHI1 */
- [MSTP312] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD2], SMSTPCR3, 12, MSTPSR3, 0), /* SDHI2 */
- [MSTP311] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_SD3], SMSTPCR3, 11, MSTPSR3, 0), /* SDHI3 */
- [MSTP305] = SH_CLK_MSTP32_STS(&div6_clks[DIV6_MMC1], SMSTPCR3, 5, MSTPSR3, 0), /* MMC1 */
- [MSTP304] = SH_CLK_MSTP32_STS(&cp_clk, SMSTPCR3, 4, MSTPSR3, 0), /* TPU0 */
- [MSTP216] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 16, MSTPSR2, 0), /* SCIFB2 */
- [MSTP207] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 7, MSTPSR2, 0), /* SCIFB1 */
- [MSTP206] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 6, MSTPSR2, 0), /* SCIFB0 */
- [MSTP204] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 4, MSTPSR2, 0), /* SCIFA0 */
- [MSTP203] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 3, MSTPSR2, 0), /* SCIFA1 */
- [MSTP202] = SH_CLK_MSTP32_STS(&mp_clk, SMSTPCR2, 2, MSTPSR2, 0), /* SCIFA2 */
- [MSTP124] = SH_CLK_MSTP32_STS(&rclk_clk, SMSTPCR1, 24, MSTPSR1, 0), /* CMT0 */
-};
-
-static struct clk_lookup lookups[] = {
-
- /* main clocks */
- CLKDEV_CON_ID("extal", &extal_clk),
- CLKDEV_CON_ID("extal_div2", &extal_div2_clk),
- CLKDEV_CON_ID("main", &main_clk),
- CLKDEV_CON_ID("pll1", &pll1_clk),
- CLKDEV_CON_ID("pll1_div2", &pll1_div2_clk),
- CLKDEV_CON_ID("pll3", &pll3_clk),
- CLKDEV_CON_ID("zg", &zg_clk),
- CLKDEV_CON_ID("zx", &zx_clk),
- CLKDEV_CON_ID("zs", &zs_clk),
- CLKDEV_CON_ID("hp", &hp_clk),
- CLKDEV_CON_ID("i", &i_clk),
- CLKDEV_CON_ID("b", &b_clk),
- CLKDEV_CON_ID("lb", &lb_clk),
- CLKDEV_CON_ID("p", &p_clk),
- CLKDEV_CON_ID("cl", &cl_clk),
- CLKDEV_CON_ID("m2", &m2_clk),
- CLKDEV_CON_ID("imp", &imp_clk),
- CLKDEV_CON_ID("rclk", &rclk_clk),
- CLKDEV_CON_ID("oscclk", &oscclk_clk),
- CLKDEV_CON_ID("zb3", &zb3_clk),
- CLKDEV_CON_ID("zb3d2", &zb3d2_clk),
- CLKDEV_CON_ID("ddr", &ddr_clk),
- CLKDEV_CON_ID("mp", &mp_clk),
- CLKDEV_CON_ID("qspi", &qspi_clk),
- CLKDEV_CON_ID("cp", &cp_clk),
-
- /* DIV4 */
- CLKDEV_CON_ID("sdh", &div4_clks[DIV4_SDH]),
-
- /* DIV6 */
- CLKDEV_CON_ID("ssp", &div6_clks[DIV6_SSP]),
- CLKDEV_CON_ID("ssprs", &div6_clks[DIV6_SSPRS]),
-
- /* MSTP */
- CLKDEV_DEV_ID("rcar_sound", &mstp_clks[MSTP1005]),
- CLKDEV_DEV_ID("sh-sci.0", &mstp_clks[MSTP204]),
- CLKDEV_DEV_ID("sh-sci.1", &mstp_clks[MSTP203]),
- CLKDEV_DEV_ID("sh-sci.2", &mstp_clks[MSTP206]),
- CLKDEV_DEV_ID("sh-sci.3", &mstp_clks[MSTP207]),
- CLKDEV_DEV_ID("sh-sci.4", &mstp_clks[MSTP216]),
- CLKDEV_DEV_ID("sh-sci.5", &mstp_clks[MSTP202]),
- CLKDEV_DEV_ID("sh-sci.6", &mstp_clks[MSTP721]),
- CLKDEV_DEV_ID("sh-sci.7", &mstp_clks[MSTP720]),
- CLKDEV_DEV_ID("sh-sci.8", &mstp_clks[MSTP717]),
- CLKDEV_DEV_ID("sh-sci.9", &mstp_clks[MSTP716]),
- CLKDEV_DEV_ID("i2c-rcar_gen2.0", &mstp_clks[MSTP931]),
- CLKDEV_DEV_ID("i2c-rcar_gen2.1", &mstp_clks[MSTP930]),
- CLKDEV_DEV_ID("i2c-rcar_gen2.2", &mstp_clks[MSTP929]),
- CLKDEV_DEV_ID("i2c-rcar_gen2.3", &mstp_clks[MSTP928]),
- CLKDEV_DEV_ID("r8a7790-ether", &mstp_clks[MSTP813]),
- CLKDEV_DEV_ID("r8a7790-vin.0", &mstp_clks[MSTP811]),
- CLKDEV_DEV_ID("r8a7790-vin.1", &mstp_clks[MSTP810]),
- CLKDEV_DEV_ID("r8a7790-vin.2", &mstp_clks[MSTP809]),
- CLKDEV_DEV_ID("r8a7790-vin.3", &mstp_clks[MSTP808]),
- CLKDEV_DEV_ID("rcar_thermal", &mstp_clks[MSTP522]),
- CLKDEV_DEV_ID("sh-dma-engine.0", &mstp_clks[MSTP502]),
- CLKDEV_DEV_ID("sh-dma-engine.1", &mstp_clks[MSTP501]),
- CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP315]),
- CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]),
- CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]),
- CLKDEV_DEV_ID("sh_mobile_sdhi.2", &mstp_clks[MSTP312]),
- CLKDEV_DEV_ID("sh_mobile_sdhi.3", &mstp_clks[MSTP311]),
- CLKDEV_DEV_ID("sh_mmcif.1", &mstp_clks[MSTP305]),
- CLKDEV_DEV_ID("qspi.0", &mstp_clks[MSTP917]),
- CLKDEV_DEV_ID("renesas_usbhs", &mstp_clks[MSTP704]),
- CLKDEV_DEV_ID("pci-rcar-gen2.0", &mstp_clks[MSTP703]),
- CLKDEV_DEV_ID("pci-rcar-gen2.1", &mstp_clks[MSTP703]),
- CLKDEV_DEV_ID("pci-rcar-gen2.2", &mstp_clks[MSTP703]),
- CLKDEV_DEV_ID("sata-r8a7790.0", &mstp_clks[MSTP815]),
- CLKDEV_DEV_ID("sata-r8a7790.1", &mstp_clks[MSTP814]),
-
- /* ICK */
- CLKDEV_ICK_ID("fck", "sh-cmt-48-gen2.0", &mstp_clks[MSTP124]),
- CLKDEV_ICK_ID("usbhs", "usb_phy_rcar_gen2", &mstp_clks[MSTP704]),
- CLKDEV_ICK_ID("lvds.0", "rcar-du-r8a7790", &mstp_clks[MSTP726]),
- CLKDEV_ICK_ID("lvds.1", "rcar-du-r8a7790", &mstp_clks[MSTP725]),
- CLKDEV_ICK_ID("du.0", "rcar-du-r8a7790", &mstp_clks[MSTP724]),
- CLKDEV_ICK_ID("du.1", "rcar-du-r8a7790", &mstp_clks[MSTP723]),
- CLKDEV_ICK_ID("du.2", "rcar-du-r8a7790", &mstp_clks[MSTP722]),
- CLKDEV_ICK_ID("clk_a", "rcar_sound", &audio_clk_a),
- CLKDEV_ICK_ID("clk_b", "rcar_sound", &audio_clk_b),
- CLKDEV_ICK_ID("clk_c", "rcar_sound", &audio_clk_c),
- CLKDEV_ICK_ID("clk_i", "rcar_sound", &m2_clk),
- CLKDEV_ICK_ID("src.0", "rcar_sound", &mstp_clks[MSTP1031]),
- CLKDEV_ICK_ID("src.1", "rcar_sound", &mstp_clks[MSTP1030]),
- CLKDEV_ICK_ID("src.2", "rcar_sound", &mstp_clks[MSTP1029]),
- CLKDEV_ICK_ID("src.3", "rcar_sound", &mstp_clks[MSTP1028]),
- CLKDEV_ICK_ID("src.4", "rcar_sound", &mstp_clks[MSTP1027]),
- CLKDEV_ICK_ID("src.5", "rcar_sound", &mstp_clks[MSTP1026]),
- CLKDEV_ICK_ID("src.6", "rcar_sound", &mstp_clks[MSTP1025]),
- CLKDEV_ICK_ID("src.7", "rcar_sound", &mstp_clks[MSTP1024]),
- CLKDEV_ICK_ID("src.8", "rcar_sound", &mstp_clks[MSTP1023]),
- CLKDEV_ICK_ID("src.9", "rcar_sound", &mstp_clks[MSTP1022]),
- CLKDEV_ICK_ID("ssi.0", "rcar_sound", &mstp_clks[MSTP1015]),
- CLKDEV_ICK_ID("ssi.1", "rcar_sound", &mstp_clks[MSTP1014]),
- CLKDEV_ICK_ID("ssi.2", "rcar_sound", &mstp_clks[MSTP1013]),
- CLKDEV_ICK_ID("ssi.3", "rcar_sound", &mstp_clks[MSTP1012]),
- CLKDEV_ICK_ID("ssi.4", "rcar_sound", &mstp_clks[MSTP1011]),
- CLKDEV_ICK_ID("ssi.5", "rcar_sound", &mstp_clks[MSTP1010]),
- CLKDEV_ICK_ID("ssi.6", "rcar_sound", &mstp_clks[MSTP1009]),
- CLKDEV_ICK_ID("ssi.7", "rcar_sound", &mstp_clks[MSTP1008]),
- CLKDEV_ICK_ID("ssi.8", "rcar_sound", &mstp_clks[MSTP1007]),
- CLKDEV_ICK_ID("ssi.9", "rcar_sound", &mstp_clks[MSTP1006]),
-
-};
-
-#define R8A7790_CLOCK_ROOT(e, m, p0, p1, p30, p31) \
- extal_clk.rate = e * 1000 * 1000; \
- main_clk.parent = m; \
- SH_CLK_SET_RATIO(&pll1_clk_ratio, p1 / 2, 1); \
- if (mode & MD(19)) \
- SH_CLK_SET_RATIO(&pll3_clk_ratio, p31, 1); \
- else \
- SH_CLK_SET_RATIO(&pll3_clk_ratio, p30, 1)
-
-
-void __init r8a7790_clock_init(void)
-{
- u32 mode = rcar_gen2_read_mode_pins();
- int k, ret = 0;
-
- switch (mode & (MD(14) | MD(13))) {
- case 0:
- R8A7790_CLOCK_ROOT(15, &extal_clk, 172, 208, 106, 88);
- break;
- case MD(13):
- R8A7790_CLOCK_ROOT(20, &extal_clk, 130, 156, 80, 66);
- break;
- case MD(14):
- R8A7790_CLOCK_ROOT(26 / 2, &extal_div2_clk, 200, 240, 122, 102);
- break;
- case MD(13) | MD(14):
- R8A7790_CLOCK_ROOT(30 / 2, &extal_div2_clk, 172, 208, 106, 88);
- break;
- }
-
- if (mode & (MD(18)))
- SH_CLK_SET_RATIO(&lb_clk_ratio, 1, 36);
- else
- SH_CLK_SET_RATIO(&lb_clk_ratio, 1, 24);
-
- if ((mode & (MD(3) | MD(2) | MD(1))) == MD(2))
- SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 16);
- else
- SH_CLK_SET_RATIO(&qspi_clk_ratio, 1, 20);
-
- for (k = 0; !ret && (k < ARRAY_SIZE(main_clks)); k++)
- ret = clk_register(main_clks[k]);
-
- if (!ret)
- ret = sh_clk_div4_register(div4_clks, DIV4_NR, &div4_table);
-
- if (!ret)
- ret = sh_clk_div6_register(div6_clks, DIV6_NR);
-
- if (!ret)
- ret = sh_clk_mstp_register(mstp_clks, MSTP_NR);
-
- clkdev_add_table(lookups, ARRAY_SIZE(lookups));
-
- if (!ret)
- shmobile_clk_init();
- else
- panic("failed to setup r8a7790 clocks\n");
-}
diff --git a/arch/arm/mach-shmobile/clock-sh73a0.c b/arch/arm/mach-shmobile/clock-sh73a0.c
index 6b4c1f313cc9..3855fb024fdb 100644
--- a/arch/arm/mach-shmobile/clock-sh73a0.c
+++ b/arch/arm/mach-shmobile/clock-sh73a0.c
@@ -553,6 +553,7 @@ enum { MSTP001,
MSTP314, MSTP313, MSTP312, MSTP311,
MSTP304, MSTP303, MSTP302, MSTP301, MSTP300,
MSTP411, MSTP410, MSTP403,
+ MSTP508,
MSTP_NR };
#define MSTP(_parent, _reg, _bit, _flags) \
@@ -597,6 +598,7 @@ static struct clk mstp_clks[MSTP_NR] = {
[MSTP411] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 11, 0), /* IIC3 */
[MSTP410] = MSTP(&div4_clks[DIV4_HP], SMSTPCR4, 10, 0), /* IIC4 */
[MSTP403] = MSTP(&r_clk, SMSTPCR4, 3, 0), /* KEYSC */
+ [MSTP508] = MSTP(&div4_clks[DIV4_HP], SMSTPCR5, 8, 0), /* INTCA0 */
};
/* The lookups structure below includes duplicate entries for some clocks
@@ -677,6 +679,14 @@ static struct clk_lookup lookups[] = {
CLKDEV_DEV_ID("i2c-sh_mobile.4", &mstp_clks[MSTP410]), /* I2C4 */
CLKDEV_DEV_ID("e6828000.i2c", &mstp_clks[MSTP410]), /* I2C4 */
CLKDEV_DEV_ID("sh_keysc.0", &mstp_clks[MSTP403]), /* KEYSC */
+ CLKDEV_DEV_ID("renesas_intc_irqpin.0", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("e6900000.irqpin", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("renesas_intc_irqpin.1", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("e6900004.irqpin", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("renesas_intc_irqpin.2", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("e6900008.irqpin", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("renesas_intc_irqpin.3", &mstp_clks[MSTP508]), /* INTCA0 */
+ CLKDEV_DEV_ID("e690000c.irqpin", &mstp_clks[MSTP508]), /* INTCA0 */
/* ICK */
CLKDEV_ICK_ID("dsit_clk", "sh-mipi-dsi.0", &div6_clks[DIV6_DSIT]),
diff --git a/arch/arm/mach-shmobile/pm-r8a7740.c b/arch/arm/mach-shmobile/pm-r8a7740.c
index ac2eecd6f5ea..34608fcf0648 100644
--- a/arch/arm/mach-shmobile/pm-r8a7740.c
+++ b/arch/arm/mach-shmobile/pm-r8a7740.c
@@ -9,10 +9,14 @@
* for more details.
*/
#include <linux/console.h>
+#include <linux/io.h>
#include <linux/suspend.h>
+
#include "common.h"
#include "pm-rmobile.h"
+#define SYSC_BASE IOMEM(0xe6180000)
+
#if defined(CONFIG_PM) && !defined(CONFIG_ARCH_MULTIPLATFORM)
static int r8a7740_pd_a3sm_suspend(void)
{
@@ -45,41 +49,51 @@ static int r8a7740_pd_d4_suspend(void)
static struct rmobile_pm_domain r8a7740_pm_domains[] = {
{
.genpd.name = "A4LC",
+ .base = SYSC_BASE,
.bit_shift = 1,
}, {
.genpd.name = "A4MP",
+ .base = SYSC_BASE,
.bit_shift = 2,
}, {
.genpd.name = "D4",
+ .base = SYSC_BASE,
.bit_shift = 3,
.gov = &pm_domain_always_on_gov,
.suspend = r8a7740_pd_d4_suspend,
}, {
.genpd.name = "A4R",
+ .base = SYSC_BASE,
.bit_shift = 5,
}, {
.genpd.name = "A3RV",
+ .base = SYSC_BASE,
.bit_shift = 6,
}, {
.genpd.name = "A4S",
+ .base = SYSC_BASE,
.bit_shift = 10,
.no_debug = true,
}, {
.genpd.name = "A3SP",
+ .base = SYSC_BASE,
.bit_shift = 11,
.gov = &pm_domain_always_on_gov,
.no_debug = true,
.suspend = r8a7740_pd_a3sp_suspend,
}, {
.genpd.name = "A3SM",
+ .base = SYSC_BASE,
.bit_shift = 12,
.gov = &pm_domain_always_on_gov,
.suspend = r8a7740_pd_a3sm_suspend,
}, {
.genpd.name = "A3SG",
+ .base = SYSC_BASE,
.bit_shift = 13,
}, {
.genpd.name = "A4SU",
+ .base = SYSC_BASE,
.bit_shift = 20,
},
};
diff --git a/arch/arm/mach-shmobile/pm-rmobile.c b/arch/arm/mach-shmobile/pm-rmobile.c
index 6f7d56ecf969..95018209ff0b 100644
--- a/arch/arm/mach-shmobile/pm-rmobile.c
+++ b/arch/arm/mach-shmobile/pm-rmobile.c
@@ -3,6 +3,7 @@
*
* Copyright (C) 2012 Renesas Solutions Corp.
* Copyright (C) 2012 Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>
+ * Copyright (C) 2014 Glider bvba
*
* based on pm-sh7372.c
* Copyright (C) 2011 Magnus Damm
@@ -13,16 +14,22 @@
*/
#include <linux/console.h>
#include <linux/delay.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_clock.h>
+#include <linux/slab.h>
+
#include <asm/io.h>
+
#include "pm-rmobile.h"
/* SYSC */
-#define SPDCR IOMEM(0xe6180008)
-#define SWUCR IOMEM(0xe6180014)
-#define PSTR IOMEM(0xe6180080)
+#define SPDCR 0x08 /* SYS Power Down Control Register */
+#define SWUCR 0x14 /* SYS Wakeup Control Register */
+#define PSTR 0x80 /* Power Status Register */
#define PSTR_RETRIES 100
#define PSTR_DELAY_US 10
@@ -30,8 +37,12 @@
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;
+ unsigned int mask;
+
+ if (rmobile_pd->bit_shift == ~0)
+ return -EBUSY;
+ mask = 1 << rmobile_pd->bit_shift;
if (rmobile_pd->suspend) {
int ret = rmobile_pd->suspend();
@@ -39,12 +50,12 @@ static int rmobile_pd_power_down(struct generic_pm_domain *genpd)
return ret;
}
- if (__raw_readl(PSTR) & mask) {
+ if (__raw_readl(rmobile_pd->base + PSTR) & mask) {
unsigned int retry_count;
- __raw_writel(mask, SPDCR);
+ __raw_writel(mask, rmobile_pd->base + SPDCR);
for (retry_count = PSTR_RETRIES; retry_count; retry_count--) {
- if (!(__raw_readl(SPDCR) & mask))
+ if (!(__raw_readl(rmobile_pd->base + SPDCR) & mask))
break;
cpu_relax();
}
@@ -52,7 +63,8 @@ static int rmobile_pd_power_down(struct generic_pm_domain *genpd)
if (!rmobile_pd->no_debug)
pr_debug("%s: Power off, 0x%08x -> PSTR = 0x%08x\n",
- genpd->name, mask, __raw_readl(PSTR));
+ genpd->name, mask,
+ __raw_readl(rmobile_pd->base + PSTR));
return 0;
}
@@ -60,17 +72,21 @@ static int rmobile_pd_power_down(struct generic_pm_domain *genpd)
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 mask;
unsigned int retry_count;
int ret = 0;
- if (__raw_readl(PSTR) & mask)
+ if (rmobile_pd->bit_shift == ~0)
+ return 0;
+
+ mask = 1 << rmobile_pd->bit_shift;
+ if (__raw_readl(rmobile_pd->base + PSTR) & mask)
goto out;
- __raw_writel(mask, SWUCR);
+ __raw_writel(mask, rmobile_pd->base + SWUCR);
for (retry_count = 2 * PSTR_RETRIES; retry_count; retry_count--) {
- if (!(__raw_readl(SWUCR) & mask))
+ if (!(__raw_readl(rmobile_pd->base + SWUCR) & mask))
break;
if (retry_count > PSTR_RETRIES)
udelay(PSTR_DELAY_US);
@@ -82,7 +98,8 @@ static int __rmobile_pd_power_up(struct rmobile_pm_domain *rmobile_pd,
if (!rmobile_pd->no_debug)
pr_debug("%s: Power on, 0x%08x -> PSTR = 0x%08x\n",
- rmobile_pd->genpd.name, mask, __raw_readl(PSTR));
+ rmobile_pd->genpd.name, mask,
+ __raw_readl(rmobile_pd->base + PSTR));
out:
if (ret == 0 && rmobile_pd->resume && do_resume)
@@ -101,6 +118,36 @@ static bool rmobile_pd_active_wakeup(struct device *dev)
return true;
}
+static int rmobile_pd_attach_dev(struct generic_pm_domain *domain,
+ struct device *dev)
+{
+ int error;
+
+ error = pm_clk_create(dev);
+ if (error) {
+ dev_err(dev, "pm_clk_create failed %d\n", error);
+ return error;
+ }
+
+ error = pm_clk_add(dev, NULL);
+ if (error) {
+ dev_err(dev, "pm_clk_add failed %d\n", error);
+ goto fail;
+ }
+
+ return 0;
+
+fail:
+ pm_clk_destroy(dev);
+ return error;
+}
+
+static void rmobile_pd_detach_dev(struct generic_pm_domain *domain,
+ struct device *dev)
+{
+ pm_clk_destroy(dev);
+}
+
static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
{
struct generic_pm_domain *genpd = &rmobile_pd->genpd;
@@ -111,9 +158,13 @@ static void rmobile_init_pm_domain(struct rmobile_pm_domain *rmobile_pd)
genpd->dev_ops.active_wakeup = rmobile_pd_active_wakeup;
genpd->power_off = rmobile_pd_power_down;
genpd->power_on = rmobile_pd_power_up;
+ genpd->attach_dev = rmobile_pd_attach_dev;
+ genpd->detach_dev = rmobile_pd_detach_dev;
__rmobile_pd_power_up(rmobile_pd, false);
}
+#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
+
void rmobile_init_domains(struct rmobile_pm_domain domains[], int num)
{
int j;
@@ -129,8 +180,6 @@ void rmobile_add_device_to_domain_td(const char *domain_name,
struct device *dev = &pdev->dev;
__pm_genpd_name_add_device(domain_name, dev, td);
- if (pm_clk_no_clocks(dev))
- pm_clk_add(dev, NULL);
}
void rmobile_add_devices_to_domains(struct pm_domain_device data[],
@@ -148,3 +197,238 @@ void rmobile_add_devices_to_domains(struct pm_domain_device data[],
rmobile_add_device_to_domain_td(data[j].domain_name,
data[j].pdev, &latencies);
}
+
+#else /* !CONFIG_ARCH_SHMOBILE_LEGACY */
+
+static int rmobile_pd_suspend_busy(void)
+{
+ /*
+ * This domain should not be turned off.
+ */
+ return -EBUSY;
+}
+
+static int rmobile_pd_suspend_console(void)
+{
+ /*
+ * Serial consoles make use of SCIF hardware located in this domain,
+ * hence keep the power domain on if "no_console_suspend" is set.
+ */
+ return console_suspend_enabled ? 0 : -EBUSY;
+}
+
+enum pd_types {
+ PD_NORMAL,
+ PD_CPU,
+ PD_CONSOLE,
+ PD_DEBUG,
+ PD_MEMCTL,
+};
+
+#define MAX_NUM_SPECIAL_PDS 16
+
+static struct special_pd {
+ struct device_node *pd;
+ enum pd_types type;
+} special_pds[MAX_NUM_SPECIAL_PDS] __initdata;
+
+static unsigned int num_special_pds __initdata;
+
+static const struct of_device_id special_ids[] __initconst = {
+ { .compatible = "arm,coresight-etm3x", .data = (void *)PD_DEBUG },
+ { .compatible = "renesas,dbsc-r8a73a4", .data = (void *)PD_MEMCTL, },
+ { .compatible = "renesas,dbsc3-r8a7740", .data = (void *)PD_MEMCTL, },
+ { .compatible = "renesas,sbsc-sh73a0", .data = (void *)PD_MEMCTL, },
+ { /* sentinel */ },
+};
+
+static void __init add_special_pd(struct device_node *np, enum pd_types type)
+{
+ unsigned int i;
+ struct device_node *pd;
+
+ pd = of_parse_phandle(np, "power-domains", 0);
+ if (!pd)
+ return;
+
+ for (i = 0; i < num_special_pds; i++)
+ if (pd == special_pds[i].pd && type == special_pds[i].type) {
+ of_node_put(pd);
+ return;
+ }
+
+ if (num_special_pds == ARRAY_SIZE(special_pds)) {
+ pr_warn("Too many special PM domains\n");
+ of_node_put(pd);
+ return;
+ }
+
+ pr_debug("Special PM domain %s type %d for %s\n", pd->name, type,
+ np->full_name);
+
+ special_pds[num_special_pds].pd = pd;
+ special_pds[num_special_pds].type = type;
+ num_special_pds++;
+}
+
+static void __init get_special_pds(void)
+{
+ struct device_node *np;
+ const struct of_device_id *id;
+
+ /* PM domains containing CPUs */
+ for_each_node_by_type(np, "cpu")
+ add_special_pd(np, PD_CPU);
+
+ /* PM domain containing console */
+ if (of_stdout)
+ add_special_pd(of_stdout, PD_CONSOLE);
+
+ /* PM domains containing other special devices */
+ for_each_matching_node_and_match(np, special_ids, &id)
+ add_special_pd(np, (enum pd_types)id->data);
+}
+
+static void __init put_special_pds(void)
+{
+ unsigned int i;
+
+ for (i = 0; i < num_special_pds; i++)
+ of_node_put(special_pds[i].pd);
+}
+
+static enum pd_types __init pd_type(const struct device_node *pd)
+{
+ unsigned int i;
+
+ for (i = 0; i < num_special_pds; i++)
+ if (pd == special_pds[i].pd)
+ return special_pds[i].type;
+
+ return PD_NORMAL;
+}
+
+static void __init rmobile_setup_pm_domain(struct device_node *np,
+ struct rmobile_pm_domain *pd)
+{
+ const char *name = pd->genpd.name;
+
+ switch (pd_type(np)) {
+ case PD_CPU:
+ /*
+ * This domain contains the CPU core and therefore it should
+ * only be turned off if the CPU is not in use.
+ */
+ pr_debug("PM domain %s contains CPU\n", name);
+ pd->gov = &pm_domain_always_on_gov;
+ pd->suspend = rmobile_pd_suspend_busy;
+ break;
+
+ case PD_CONSOLE:
+ pr_debug("PM domain %s contains serial console\n", name);
+ pd->gov = &pm_domain_always_on_gov;
+ pd->suspend = rmobile_pd_suspend_console;
+ break;
+
+ case PD_DEBUG:
+ /*
+ * This domain contains the Coresight-ETM hardware block and
+ * therefore it should only be turned off if the debug module
+ * is not in use.
+ */
+ pr_debug("PM domain %s contains Coresight-ETM\n", name);
+ pd->gov = &pm_domain_always_on_gov;
+ pd->suspend = rmobile_pd_suspend_busy;
+ break;
+
+ case PD_MEMCTL:
+ /*
+ * This domain contains a memory-controller and therefore it
+ * should only be turned off if memory is not in use.
+ */
+ pr_debug("PM domain %s contains MEMCTL\n", name);
+ pd->gov = &pm_domain_always_on_gov;
+ pd->suspend = rmobile_pd_suspend_busy;
+ break;
+
+ case PD_NORMAL:
+ break;
+ }
+
+ rmobile_init_pm_domain(pd);
+}
+
+static int __init rmobile_add_pm_domains(void __iomem *base,
+ struct device_node *parent,
+ struct generic_pm_domain *genpd_parent)
+{
+ struct device_node *np;
+
+ for_each_child_of_node(parent, np) {
+ struct rmobile_pm_domain *pd;
+ u32 idx = ~0;
+
+ if (of_property_read_u32(np, "reg", &idx)) {
+ /* always-on domain */
+ }
+
+ pd = kzalloc(sizeof(*pd), GFP_KERNEL);
+ if (!pd)
+ return -ENOMEM;
+
+ pd->genpd.name = np->name;
+ pd->base = base;
+ pd->bit_shift = idx;
+
+ rmobile_setup_pm_domain(np, pd);
+ if (genpd_parent)
+ pm_genpd_add_subdomain(genpd_parent, &pd->genpd);
+ of_genpd_add_provider_simple(np, &pd->genpd);
+
+ rmobile_add_pm_domains(base, np, &pd->genpd);
+ }
+ return 0;
+}
+
+static int __init rmobile_init_pm_domains(void)
+{
+ struct device_node *np, *pmd;
+ bool scanned = false;
+ void __iomem *base;
+ int ret = 0;
+
+ for_each_compatible_node(np, NULL, "renesas,sysc-rmobile") {
+ base = of_iomap(np, 0);
+ if (!base) {
+ pr_warn("%s cannot map reg 0\n", np->full_name);
+ continue;
+ }
+
+ pmd = of_get_child_by_name(np, "pm-domains");
+ if (!pmd) {
+ pr_warn("%s lacks pm-domains node\n", np->full_name);
+ continue;
+ }
+
+ if (!scanned) {
+ /* Find PM domains containing special blocks */
+ get_special_pds();
+ scanned = true;
+ }
+
+ ret = rmobile_add_pm_domains(base, pmd, NULL);
+ of_node_put(pmd);
+ if (ret) {
+ of_node_put(np);
+ break;
+ }
+ }
+
+ put_special_pds();
+
+ return ret;
+}
+
+core_initcall(rmobile_init_pm_domains);
+
+#endif /* !CONFIG_ARCH_SHMOBILE_LEGACY */
diff --git a/arch/arm/mach-shmobile/pm-rmobile.h b/arch/arm/mach-shmobile/pm-rmobile.h
index 8f66b343162b..53219786f539 100644
--- a/arch/arm/mach-shmobile/pm-rmobile.h
+++ b/arch/arm/mach-shmobile/pm-rmobile.h
@@ -21,6 +21,7 @@ struct rmobile_pm_domain {
struct dev_power_governor *gov;
int (*suspend)(void);
void (*resume)(void);
+ void __iomem *base;
unsigned int bit_shift;
bool no_debug;
};
@@ -36,7 +37,7 @@ struct pm_domain_device {
struct platform_device *pdev;
};
-#ifdef CONFIG_PM_RMOBILE
+#if defined(CONFIG_PM_RMOBILE) && defined(CONFIG_ARCH_SHMOBILE_LEGACY)
extern void rmobile_init_domains(struct rmobile_pm_domain domains[], int num);
extern void rmobile_add_device_to_domain_td(const char *domain_name,
struct platform_device *pdev,
diff --git a/arch/arm/mach-shmobile/pm-sh7372.c b/arch/arm/mach-shmobile/pm-sh7372.c
index 0e37da654ed5..c0293ae4b013 100644
--- a/arch/arm/mach-shmobile/pm-sh7372.c
+++ b/arch/arm/mach-shmobile/pm-sh7372.c
@@ -45,6 +45,8 @@
#define PLLC01STPCR IOMEM(0xe61500c8)
/* SYSC */
+#define SYSC_BASE IOMEM(0xe6180000)
+
#define SBAR IOMEM(0xe6180020)
#define WUPRMSK IOMEM(0xe6180028)
#define WUPSMSK IOMEM(0xe618002c)
@@ -118,24 +120,28 @@ static struct rmobile_pm_domain sh7372_pm_domains[] = {
.genpd.name = "A4LC",
.genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
.genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .base = SYSC_BASE,
.bit_shift = 1,
},
{
.genpd.name = "A4MP",
.genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
.genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .base = SYSC_BASE,
.bit_shift = 2,
},
{
.genpd.name = "D4",
.genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
.genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .base = SYSC_BASE,
.bit_shift = 3,
},
{
.genpd.name = "A4R",
.genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
.genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .base = SYSC_BASE,
.bit_shift = 5,
.suspend = sh7372_a4r_pd_suspend,
.resume = sh7372_intcs_resume,
@@ -144,18 +150,21 @@ static struct rmobile_pm_domain sh7372_pm_domains[] = {
.genpd.name = "A3RV",
.genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
.genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .base = SYSC_BASE,
.bit_shift = 6,
},
{
.genpd.name = "A3RI",
.genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
.genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .base = SYSC_BASE,
.bit_shift = 8,
},
{
.genpd.name = "A4S",
.genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
.genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .base = SYSC_BASE,
.bit_shift = 10,
.gov = &pm_domain_always_on_gov,
.no_debug = true,
@@ -166,6 +175,7 @@ static struct rmobile_pm_domain sh7372_pm_domains[] = {
.genpd.name = "A3SP",
.genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
.genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .base = SYSC_BASE,
.bit_shift = 11,
.gov = &pm_domain_always_on_gov,
.no_debug = true,
@@ -175,6 +185,7 @@ static struct rmobile_pm_domain sh7372_pm_domains[] = {
.genpd.name = "A3SG",
.genpd.power_on_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
.genpd.power_off_latency_ns = PM_DOMAIN_ON_OFF_LATENCY_NS,
+ .base = SYSC_BASE,
.bit_shift = 13,
},
};
diff --git a/arch/arm/mach-shmobile/r8a7790.h b/arch/arm/mach-shmobile/r8a7790.h
index 388f0514d931..bf73a850aaed 100644
--- a/arch/arm/mach-shmobile/r8a7790.h
+++ b/arch/arm/mach-shmobile/r8a7790.h
@@ -1,34 +1,6 @@
#ifndef __ASM_R8A7790_H__
#define __ASM_R8A7790_H__
-/* DMA slave IDs */
-enum {
- RCAR_DMA_SLAVE_INVALID,
- AUDIO_DMAC_SLAVE_SSI0_TX,
- AUDIO_DMAC_SLAVE_SSI0_RX,
- AUDIO_DMAC_SLAVE_SSI1_TX,
- AUDIO_DMAC_SLAVE_SSI1_RX,
- AUDIO_DMAC_SLAVE_SSI2_TX,
- AUDIO_DMAC_SLAVE_SSI2_RX,
- AUDIO_DMAC_SLAVE_SSI3_TX,
- AUDIO_DMAC_SLAVE_SSI3_RX,
- AUDIO_DMAC_SLAVE_SSI4_TX,
- AUDIO_DMAC_SLAVE_SSI4_RX,
- AUDIO_DMAC_SLAVE_SSI5_TX,
- AUDIO_DMAC_SLAVE_SSI5_RX,
- AUDIO_DMAC_SLAVE_SSI6_TX,
- AUDIO_DMAC_SLAVE_SSI6_RX,
- AUDIO_DMAC_SLAVE_SSI7_TX,
- AUDIO_DMAC_SLAVE_SSI7_RX,
- AUDIO_DMAC_SLAVE_SSI8_TX,
- AUDIO_DMAC_SLAVE_SSI8_RX,
- AUDIO_DMAC_SLAVE_SSI9_TX,
- AUDIO_DMAC_SLAVE_SSI9_RX,
-};
-
-void r8a7790_add_standard_devices(void);
-void r8a7790_clock_init(void);
-void r8a7790_pinmux_init(void);
void r8a7790_pm_init(void);
extern struct smp_operations r8a7790_smp_ops;
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c
index 79ad93dfdae4..dd64caf79216 100644
--- a/arch/arm/mach-shmobile/setup-r8a7740.c
+++ b/arch/arm/mach-shmobile/setup-r8a7740.c
@@ -656,7 +656,7 @@ static struct resource pmu_resources[] = {
};
static struct platform_device pmu_device = {
- .name = "arm-pmu",
+ .name = "armv7-pmu",
.id = -1,
.num_resources = ARRAY_SIZE(pmu_resources),
.resource = pmu_resources,
@@ -800,7 +800,14 @@ void __init r8a7740_init_irq_of(void)
void __iomem *intc_msk_base = ioremap_nocache(0xe6900040, 0x10);
void __iomem *pfc_inta_ctrl = ioremap_nocache(0xe605807c, 0x4);
+#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
+ void __iomem *gic_dist_base = ioremap_nocache(0xc2800000, 0x1000);
+ void __iomem *gic_cpu_base = ioremap_nocache(0xc2000000, 0x1000);
+
+ gic_init(0, 29, gic_dist_base, gic_cpu_base);
+#else
irqchip_init();
+#endif
/* route signals to GIC */
iowrite32(0x0, pfc_inta_ctrl);
diff --git a/arch/arm/mach-shmobile/setup-r8a7778.c b/arch/arm/mach-shmobile/setup-r8a7778.c
index 170bd146ba17..cef8895a9b82 100644
--- a/arch/arm/mach-shmobile/setup-r8a7778.c
+++ b/arch/arm/mach-shmobile/setup-r8a7778.c
@@ -576,11 +576,18 @@ void __init r8a7778_init_irq_extpin(int irlm)
void __init r8a7778_init_irq_dt(void)
{
void __iomem *base = ioremap_nocache(0xfe700000, 0x00100000);
+#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
+ void __iomem *gic_dist_base = ioremap_nocache(0xfe438000, 0x1000);
+ void __iomem *gic_cpu_base = ioremap_nocache(0xfe430000, 0x1000);
+#endif
BUG_ON(!base);
+#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
+ gic_init(0, 29, gic_dist_base, gic_cpu_base);
+#else
irqchip_init();
-
+#endif
/* route all interrupts to ARM */
__raw_writel(0x73ffffff, base + INT2NTSR0);
__raw_writel(0xffffffff, base + INT2NTSR1);
diff --git a/arch/arm/mach-shmobile/setup-r8a7779.c b/arch/arm/mach-shmobile/setup-r8a7779.c
index 6156d172cf31..27dceaf9e688 100644
--- a/arch/arm/mach-shmobile/setup-r8a7779.c
+++ b/arch/arm/mach-shmobile/setup-r8a7779.c
@@ -720,10 +720,17 @@ static int r8a7779_set_wake(struct irq_data *data, unsigned int on)
void __init r8a7779_init_irq_dt(void)
{
+#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
+ void __iomem *gic_dist_base = ioremap_nocache(0xf0001000, 0x1000);
+ void __iomem *gic_cpu_base = ioremap_nocache(0xf0000100, 0x1000);
+#endif
gic_arch_extn.irq_set_wake = r8a7779_set_wake;
+#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
+ gic_init(0, 29, gic_dist_base, gic_cpu_base);
+#else
irqchip_init();
-
+#endif
/* route all interrupts to ARM */
__raw_writel(0xffffffff, INT2NTSR0);
__raw_writel(0x3fffffff, INT2NTSR1);
diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c
index ec7d97dca4de..3a18af4922b4 100644
--- a/arch/arm/mach-shmobile/setup-r8a7790.c
+++ b/arch/arm/mach-shmobile/setup-r8a7790.c
@@ -14,295 +14,14 @@
* GNU General Public License for more details.
*/
-#include <linux/irq.h>
-#include <linux/kernel.h>
-#include <linux/of_platform.h>
-#include <linux/platform_data/gpio-rcar.h>
-#include <linux/platform_data/irq-renesas-irqc.h>
-#include <linux/serial_sci.h>
-#include <linux/sh_dma.h>
-#include <linux/sh_timer.h>
+#include <linux/init.h>
#include <asm/mach/arch.h>
#include "common.h"
-#include "dma-register.h"
-#include "irqs.h"
#include "r8a7790.h"
#include "rcar-gen2.h"
-/* Audio-DMAC */
-#define AUDIO_DMAC_SLAVE(_id, _addr, t, r) \
-{ \
- .slave_id = AUDIO_DMAC_SLAVE_## _id ##_TX, \
- .addr = _addr + 0x8, \
- .chcr = CHCR_TX(XMIT_SZ_32BIT), \
- .mid_rid = t, \
-}, { \
- .slave_id = AUDIO_DMAC_SLAVE_## _id ##_RX, \
- .addr = _addr + 0xc, \
- .chcr = CHCR_RX(XMIT_SZ_32BIT), \
- .mid_rid = r, \
-}
-
-static const struct sh_dmae_slave_config r8a7790_audio_dmac_slaves[] = {
- AUDIO_DMAC_SLAVE(SSI0, 0xec241000, 0x01, 0x02),
- AUDIO_DMAC_SLAVE(SSI1, 0xec241040, 0x03, 0x04),
- AUDIO_DMAC_SLAVE(SSI2, 0xec241080, 0x05, 0x06),
- AUDIO_DMAC_SLAVE(SSI3, 0xec2410c0, 0x07, 0x08),
- AUDIO_DMAC_SLAVE(SSI4, 0xec241100, 0x09, 0x0a),
- AUDIO_DMAC_SLAVE(SSI5, 0xec241140, 0x0b, 0x0c),
- AUDIO_DMAC_SLAVE(SSI6, 0xec241180, 0x0d, 0x0e),
- AUDIO_DMAC_SLAVE(SSI7, 0xec2411c0, 0x0f, 0x10),
- AUDIO_DMAC_SLAVE(SSI8, 0xec241200, 0x11, 0x12),
- AUDIO_DMAC_SLAVE(SSI9, 0xec241240, 0x13, 0x14),
-};
-
-#define DMAE_CHANNEL(a, b) \
-{ \
- .offset = (a) - 0x20, \
- .dmars = (a) - 0x20 + 0x40, \
- .chclr_bit = (b), \
- .chclr_offset = 0x80 - 0x20, \
-}
-
-static const struct sh_dmae_channel r8a7790_audio_dmac_channels[] = {
- DMAE_CHANNEL(0x8000, 0),
- DMAE_CHANNEL(0x8080, 1),
- DMAE_CHANNEL(0x8100, 2),
- DMAE_CHANNEL(0x8180, 3),
- DMAE_CHANNEL(0x8200, 4),
- DMAE_CHANNEL(0x8280, 5),
- DMAE_CHANNEL(0x8300, 6),
- DMAE_CHANNEL(0x8380, 7),
- DMAE_CHANNEL(0x8400, 8),
- DMAE_CHANNEL(0x8480, 9),
- DMAE_CHANNEL(0x8500, 10),
- DMAE_CHANNEL(0x8580, 11),
- DMAE_CHANNEL(0x8600, 12),
-};
-
-static struct sh_dmae_pdata r8a7790_audio_dmac_platform_data = {
- .slave = r8a7790_audio_dmac_slaves,
- .slave_num = ARRAY_SIZE(r8a7790_audio_dmac_slaves),
- .channel = r8a7790_audio_dmac_channels,
- .channel_num = ARRAY_SIZE(r8a7790_audio_dmac_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,
- .chclr_bitwise = 1,
-};
-
-static struct resource r8a7790_audio_dmac_resources[] = {
- /* Channel registers and DMAOR for low */
- DEFINE_RES_MEM(0xec700020, 0x8663 - 0x20),
- DEFINE_RES_IRQ(gic_spi(346)),
- DEFINE_RES_NAMED(gic_spi(320), 13, NULL, IORESOURCE_IRQ),
-
- /* Channel registers and DMAOR for hi */
- DEFINE_RES_MEM(0xec720020, 0x8663 - 0x20), /* hi */
- DEFINE_RES_IRQ(gic_spi(347)),
- DEFINE_RES_NAMED(gic_spi(333), 13, NULL, IORESOURCE_IRQ),
-};
-
-#define r8a7790_register_audio_dmac(id) \
- platform_device_register_resndata( \
- NULL, "sh-dma-engine", id, \
- &r8a7790_audio_dmac_resources[id * 3], 3, \
- &r8a7790_audio_dmac_platform_data, \
- sizeof(r8a7790_audio_dmac_platform_data))
-
-static const struct resource pfc_resources[] __initconst = {
- DEFINE_RES_MEM(0xe6060000, 0x250),
-};
-
-#define r8a7790_register_pfc() \
- platform_device_register_simple("pfc-r8a7790", -1, pfc_resources, \
- ARRAY_SIZE(pfc_resources))
-
-#define R8A7790_GPIO(idx) \
-static const struct resource r8a7790_gpio##idx##_resources[] __initconst = { \
- DEFINE_RES_MEM(0xe6050000 + 0x1000 * (idx), 0x50), \
- DEFINE_RES_IRQ(gic_spi(4 + (idx))), \
-}; \
- \
-static const struct gpio_rcar_config \
-r8a7790_gpio##idx##_platform_data __initconst = { \
- .gpio_base = 32 * (idx), \
- .irq_base = 0, \
- .number_of_pins = 32, \
- .pctl_name = "pfc-r8a7790", \
- .has_both_edge_trigger = 1, \
-}; \
-
-R8A7790_GPIO(0);
-R8A7790_GPIO(1);
-R8A7790_GPIO(2);
-R8A7790_GPIO(3);
-R8A7790_GPIO(4);
-R8A7790_GPIO(5);
-
-#define r8a7790_register_gpio(idx) \
- platform_device_register_resndata(NULL, "gpio_rcar", idx, \
- r8a7790_gpio##idx##_resources, \
- ARRAY_SIZE(r8a7790_gpio##idx##_resources), \
- &r8a7790_gpio##idx##_platform_data, \
- sizeof(r8a7790_gpio##idx##_platform_data))
-
-static struct resource i2c_resources[] __initdata = {
- /* I2C0 */
- DEFINE_RES_MEM(0xE6508000, 0x40),
- DEFINE_RES_IRQ(gic_spi(287)),
- /* I2C1 */
- DEFINE_RES_MEM(0xE6518000, 0x40),
- DEFINE_RES_IRQ(gic_spi(288)),
- /* I2C2 */
- DEFINE_RES_MEM(0xE6530000, 0x40),
- DEFINE_RES_IRQ(gic_spi(286)),
- /* I2C3 */
- DEFINE_RES_MEM(0xE6540000, 0x40),
- DEFINE_RES_IRQ(gic_spi(290)),
-
-};
-
-#define r8a7790_register_i2c(idx) \
- platform_device_register_simple( \
- "i2c-rcar_gen2", idx, \
- i2c_resources + (2 * idx), 2); \
-
-void __init r8a7790_pinmux_init(void)
-{
- r8a7790_register_pfc();
- r8a7790_register_gpio(0);
- r8a7790_register_gpio(1);
- r8a7790_register_gpio(2);
- r8a7790_register_gpio(3);
- r8a7790_register_gpio(4);
- r8a7790_register_gpio(5);
-}
-
-#define __R8A7790_SCIF(scif_type, _scscr, index, baseaddr, irq) \
-static struct plat_sci_port scif##index##_platform_data = { \
- .type = scif_type, \
- .flags = UPF_BOOT_AUTOCONF | UPF_IOREMAP, \
- .scscr = _scscr, \
-}; \
- \
-static struct resource scif##index##_resources[] = { \
- DEFINE_RES_MEM(baseaddr, 0x100), \
- DEFINE_RES_IRQ(irq), \
-}
-
-#define R8A7790_SCIF(index, baseaddr, irq) \
- __R8A7790_SCIF(PORT_SCIF, SCSCR_RE | SCSCR_TE, \
- index, baseaddr, irq)
-
-#define R8A7790_SCIFA(index, baseaddr, irq) \
- __R8A7790_SCIF(PORT_SCIFA, SCSCR_RE | SCSCR_TE | SCSCR_CKE0, \
- index, baseaddr, irq)
-
-#define R8A7790_SCIFB(index, baseaddr, irq) \
- __R8A7790_SCIF(PORT_SCIFB, SCSCR_RE | SCSCR_TE, \
- index, baseaddr, irq)
-
-#define R8A7790_HSCIF(index, baseaddr, irq) \
- __R8A7790_SCIF(PORT_HSCIF, SCSCR_RE | SCSCR_TE, \
- index, baseaddr, irq)
-
-R8A7790_SCIFA(0, 0xe6c40000, gic_spi(144)); /* SCIFA0 */
-R8A7790_SCIFA(1, 0xe6c50000, gic_spi(145)); /* SCIFA1 */
-R8A7790_SCIFB(2, 0xe6c20000, gic_spi(148)); /* SCIFB0 */
-R8A7790_SCIFB(3, 0xe6c30000, gic_spi(149)); /* SCIFB1 */
-R8A7790_SCIFB(4, 0xe6ce0000, gic_spi(150)); /* SCIFB2 */
-R8A7790_SCIFA(5, 0xe6c60000, gic_spi(151)); /* SCIFA2 */
-R8A7790_SCIF(6, 0xe6e60000, gic_spi(152)); /* SCIF0 */
-R8A7790_SCIF(7, 0xe6e68000, gic_spi(153)); /* SCIF1 */
-R8A7790_HSCIF(8, 0xe62c0000, gic_spi(154)); /* HSCIF0 */
-R8A7790_HSCIF(9, 0xe62c8000, gic_spi(155)); /* HSCIF1 */
-
-#define r8a7790_register_scif(index) \
- platform_device_register_resndata(NULL, "sh-sci", index, \
- scif##index##_resources, \
- ARRAY_SIZE(scif##index##_resources), \
- &scif##index##_platform_data, \
- sizeof(scif##index##_platform_data))
-
-static const struct renesas_irqc_config irqc0_data __initconst = {
- .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */
-};
-
-static const struct resource irqc0_resources[] __initconst = {
- DEFINE_RES_MEM(0xe61c0000, 0x200), /* IRQC Event Detector Block_0 */
- DEFINE_RES_IRQ(gic_spi(0)), /* IRQ0 */
- DEFINE_RES_IRQ(gic_spi(1)), /* IRQ1 */
- DEFINE_RES_IRQ(gic_spi(2)), /* IRQ2 */
- DEFINE_RES_IRQ(gic_spi(3)), /* IRQ3 */
-};
-
-#define r8a7790_register_irqc(idx) \
- platform_device_register_resndata(NULL, "renesas_irqc", \
- idx, irqc##idx##_resources, \
- ARRAY_SIZE(irqc##idx##_resources), \
- &irqc##idx##_data, \
- sizeof(struct renesas_irqc_config))
-
-static const struct resource thermal_resources[] __initconst = {
- DEFINE_RES_MEM(0xe61f0000, 0x14),
- DEFINE_RES_MEM(0xe61f0100, 0x38),
- DEFINE_RES_IRQ(gic_spi(69)),
-};
-
-#define r8a7790_register_thermal() \
- platform_device_register_simple("rcar_thermal", -1, \
- thermal_resources, \
- ARRAY_SIZE(thermal_resources))
-
-static struct sh_timer_config cmt0_platform_data = {
- .channels_mask = 0x60,
-};
-
-static struct resource cmt0_resources[] = {
- DEFINE_RES_MEM(0xffca0000, 0x1004),
- DEFINE_RES_IRQ(gic_spi(142)),
-};
-
-#define r8a7790_register_cmt(idx) \
- platform_device_register_resndata(NULL, "sh-cmt-48-gen2", \
- idx, cmt##idx##_resources, \
- ARRAY_SIZE(cmt##idx##_resources), \
- &cmt##idx##_platform_data, \
- sizeof(struct sh_timer_config))
-
-void __init r8a7790_add_standard_devices(void)
-{
- r8a7790_register_scif(0);
- r8a7790_register_scif(1);
- r8a7790_register_scif(2);
- r8a7790_register_scif(3);
- r8a7790_register_scif(4);
- r8a7790_register_scif(5);
- r8a7790_register_scif(6);
- r8a7790_register_scif(7);
- r8a7790_register_scif(8);
- r8a7790_register_scif(9);
- r8a7790_register_cmt(0);
- r8a7790_register_irqc(0);
- r8a7790_register_thermal();
- r8a7790_register_i2c(0);
- r8a7790_register_i2c(1);
- r8a7790_register_i2c(2);
- r8a7790_register_i2c(3);
- r8a7790_register_audio_dmac(0);
- r8a7790_register_audio_dmac(1);
-}
-
-#ifdef CONFIG_USE_OF
-
static const char * const r8a7790_boards_compat_dt[] __initconst = {
"renesas,r8a7790",
NULL,
@@ -316,4 +35,3 @@ DT_MACHINE_START(R8A7790_DT, "Generic R8A7790 (Flattened Device Tree)")
.reserve = rcar_gen2_reserve,
.dt_compat = r8a7790_boards_compat_dt,
MACHINE_END
-#endif /* CONFIG_USE_OF */
diff --git a/arch/arm/mach-shmobile/setup-rcar-gen2.c b/arch/arm/mach-shmobile/setup-rcar-gen2.c
index 3dd6edd9bd1d..d1fa625e61f5 100644
--- a/arch/arm/mach-shmobile/setup-rcar-gen2.c
+++ b/arch/arm/mach-shmobile/setup-rcar-gen2.c
@@ -52,15 +52,13 @@ void __init rcar_gen2_timer_init(void)
{
#if defined(CONFIG_ARM_ARCH_TIMER) || defined(CONFIG_COMMON_CLK)
u32 mode = rcar_gen2_read_mode_pins();
- bool is_e2 = (bool)of_find_compatible_node(NULL, NULL,
- "renesas,r8a7794");
#endif
#ifdef CONFIG_ARM_ARCH_TIMER
void __iomem *base;
int extal_mhz = 0;
u32 freq;
- if (is_e2) {
+ if (of_machine_is_compatible("renesas,r8a7794")) {
freq = 260000000 / 8; /* ZS / 8 */
/* CNTVOFF has to be initialized either from non-secure
* Hypervisor mode or secure Monitor mode with SCR.NS==1.
@@ -133,7 +131,9 @@ void __init rcar_gen2_timer_init(void)
#ifdef CONFIG_COMMON_CLK
rcar_gen2_clocks_init(mode);
#endif
+#ifdef CONFIG_ARCH_SHMOBILE_MULTI
clocksource_of_init();
+#endif
}
struct memory_reserve_config {
diff --git a/arch/arm/mach-shmobile/setup-sh73a0.c b/arch/arm/mach-shmobile/setup-sh73a0.c
index 93ebe3430bfe..a8593d1241be 100644
--- a/arch/arm/mach-shmobile/setup-sh73a0.c
+++ b/arch/arm/mach-shmobile/setup-sh73a0.c
@@ -563,7 +563,7 @@ static struct resource pmu_resources[] = {
};
static struct platform_device pmu_device = {
- .name = "arm-pmu",
+ .name = "armv7-pmu",
.id = -1,
.num_resources = ARRAY_SIZE(pmu_resources),
.resource = pmu_resources,
@@ -595,6 +595,7 @@ static struct platform_device ipmmu_device = {
static struct renesas_intc_irqpin_config irqpin0_platform_data = {
.irq_base = irq_pin(0), /* IRQ0 -> IRQ7 */
+ .control_parent = true,
};
static struct resource irqpin0_resources[] = {
@@ -656,6 +657,7 @@ static struct platform_device irqpin1_device = {
static struct renesas_intc_irqpin_config irqpin2_platform_data = {
.irq_base = irq_pin(16), /* IRQ16 -> IRQ23 */
+ .control_parent = true,
};
static struct resource irqpin2_resources[] = {
@@ -686,6 +688,7 @@ static struct platform_device irqpin2_device = {
static struct renesas_intc_irqpin_config irqpin3_platform_data = {
.irq_base = irq_pin(24), /* IRQ24 -> IRQ31 */
+ .control_parent = true,
};
static struct resource irqpin3_resources[] = {
diff --git a/arch/arm/mach-shmobile/smp-r8a7779.c b/arch/arm/mach-shmobile/smp-r8a7779.c
index 3f761f839043..9fc280e24ef4 100644
--- a/arch/arm/mach-shmobile/smp-r8a7779.c
+++ b/arch/arm/mach-shmobile/smp-r8a7779.c
@@ -56,7 +56,7 @@ static struct rcar_sysc_ch *r8a7779_ch_cpu[4] = {
[3] = &r8a7779_ch_cpu3,
};
-#ifdef CONFIG_HAVE_ARM_TWD
+#if defined(CONFIG_HAVE_ARM_TWD) && !defined(CONFIG_ARCH_MULTIPLATFORM)
static DEFINE_TWD_LOCAL_TIMER(twd_local_timer, R8A7779_SCU_BASE + 0x600, 29);
void __init r8a7779_register_twd(void)
{
diff --git a/arch/arm/mach-shmobile/timer.c b/arch/arm/mach-shmobile/timer.c
index f1d027aa7a81..0edf2a6d2bbe 100644
--- a/arch/arm/mach-shmobile/timer.c
+++ b/arch/arm/mach-shmobile/timer.c
@@ -70,6 +70,18 @@ void __init shmobile_init_delay(void)
if (!max_freq)
return;
+#ifdef CONFIG_ARCH_SHMOBILE_LEGACY
+ /* Non-multiplatform r8a73a4 SoC cannot use arch timer due
+ * to GIC being initialized from C and arch timer via DT */
+ if (of_machine_is_compatible("renesas,r8a73a4"))
+ has_arch_timer = false;
+
+ /* Non-multiplatform r8a7790 SoC cannot use arch timer due
+ * to GIC being initialized from C and arch timer via DT */
+ if (of_machine_is_compatible("renesas,r8a7790"))
+ has_arch_timer = false;
+#endif
+
if (!has_arch_timer || !IS_ENABLED(CONFIG_ARM_ARCH_TIMER)) {
if (is_a7_a8_a9)
shmobile_setup_delay_hz(max_freq, 1, 3);
diff --git a/arch/arm/mach-sti/board-dt.c b/arch/arm/mach-sti/board-dt.c
index 3cf6ef8d4317..b067390cef4e 100644
--- a/arch/arm/mach-sti/board-dt.c
+++ b/arch/arm/mach-sti/board-dt.c
@@ -18,6 +18,7 @@ static const char *stih41x_dt_match[] __initdata = {
"st,stih415",
"st,stih416",
"st,stih407",
+ "st,stih418",
NULL
};
diff --git a/arch/arm/mach-sunxi/platsmp.c b/arch/arm/mach-sunxi/platsmp.c
index e44d028555a4..587b0468efcc 100644
--- a/arch/arm/mach-sunxi/platsmp.c
+++ b/arch/arm/mach-sunxi/platsmp.c
@@ -120,4 +120,4 @@ static struct smp_operations sun6i_smp_ops __initdata = {
.smp_prepare_cpus = sun6i_smp_prepare_cpus,
.smp_boot_secondary = sun6i_smp_boot_secondary,
};
-CPU_METHOD_OF_DECLARE(sun6i_smp, "allwinner,sun6i-a31", &sun6i_smp_ops);
+CPU_METHOD_OF_DECLARE(sun6i_a31_smp, "allwinner,sun6i-a31", &sun6i_smp_ops);
diff --git a/arch/arm/mach-sunxi/sunxi.c b/arch/arm/mach-sunxi/sunxi.c
index 1f986758784a..1bc811a74a9f 100644
--- a/arch/arm/mach-sunxi/sunxi.c
+++ b/arch/arm/mach-sunxi/sunxi.c
@@ -13,9 +13,15 @@
#include <linux/clk-provider.h>
#include <linux/clocksource.h>
#include <linux/init.h>
+#include <linux/platform_device.h>
#include <asm/mach/arch.h>
+static void __init sunxi_dt_cpufreq_init(void)
+{
+ platform_device_register_simple("cpufreq-dt", -1, NULL, 0);
+}
+
static const char * const sunxi_board_dt_compat[] = {
"allwinner,sun4i-a10",
"allwinner,sun5i-a10s",
@@ -25,10 +31,12 @@ static const char * const sunxi_board_dt_compat[] = {
DT_MACHINE_START(SUNXI_DT, "Allwinner A1X (Device Tree)")
.dt_compat = sunxi_board_dt_compat,
+ .init_late = sunxi_dt_cpufreq_init,
MACHINE_END
static const char * const sun6i_board_dt_compat[] = {
"allwinner,sun6i-a31",
+ "allwinner,sun6i-a31s",
NULL,
};
@@ -44,6 +52,7 @@ static void __init sun6i_timer_init(void)
DT_MACHINE_START(SUN6I_DT, "Allwinner sun6i (A31) Family")
.init_time = sun6i_timer_init,
.dt_compat = sun6i_board_dt_compat,
+ .init_late = sunxi_dt_cpufreq_init,
MACHINE_END
static const char * const sun7i_board_dt_compat[] = {
@@ -53,6 +62,7 @@ static const char * const sun7i_board_dt_compat[] = {
DT_MACHINE_START(SUN7I_DT, "Allwinner sun7i (A20) Family")
.dt_compat = sun7i_board_dt_compat,
+ .init_late = sunxi_dt_cpufreq_init,
MACHINE_END
static const char * const sun8i_board_dt_compat[] = {
@@ -62,6 +72,7 @@ static const char * const sun8i_board_dt_compat[] = {
DT_MACHINE_START(SUN8I_DT, "Allwinner sun8i (A23) Family")
.dt_compat = sun8i_board_dt_compat,
+ .init_late = sunxi_dt_cpufreq_init,
MACHINE_END
static const char * const sun9i_board_dt_compat[] = {
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index d0be9a1ef6b8..5d1a318f1302 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -27,6 +27,7 @@ config ARCH_TEGRA_2x_SOC
select PINCTRL_TEGRA20
select PL310_ERRATA_727915 if CACHE_L2X0
select PL310_ERRATA_769419 if CACHE_L2X0
+ select TEGRA_TIMER
help
Support for NVIDIA Tegra AP20 and T20 processors, based on the
ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
@@ -37,6 +38,7 @@ config ARCH_TEGRA_3x_SOC
select ARM_ERRATA_764369 if SMP
select PINCTRL_TEGRA30
select PL310_ERRATA_769419 if CACHE_L2X0
+ select TEGRA_TIMER
help
Support for NVIDIA Tegra T30 processor family, based on the
ARM CortexA9MP CPU and the ARM PL310 L2 cache controller
@@ -47,6 +49,7 @@ config ARCH_TEGRA_114_SOC
select ARM_L1_CACHE_SHIFT_6
select HAVE_ARM_ARCH_TIMER
select PINCTRL_TEGRA114
+ select TEGRA_TIMER
help
Support for NVIDIA Tegra T114 processor family, based on the
ARM CortexA15MP CPU
@@ -56,6 +59,7 @@ config ARCH_TEGRA_124_SOC
select ARM_L1_CACHE_SHIFT_6
select HAVE_ARM_ARCH_TIMER
select PINCTRL_TEGRA124
+ select TEGRA_TIMER
help
Support for NVIDIA Tegra T124 processor family, based on the
ARM CortexA15MP CPU
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
index 08fb8c89f414..6ea09fe53426 100644
--- a/arch/arm/mach-versatile/core.c
+++ b/arch/arm/mach-versatile/core.c
@@ -728,43 +728,6 @@ struct of_dev_auxdata versatile_auxdata_lookup[] __initdata = {
};
#endif
-#ifdef CONFIG_LEDS
-#define VA_LEDS_BASE (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET)
-
-static void versatile_leds_event(led_event_t ledevt)
-{
- unsigned long flags;
- u32 val;
-
- local_irq_save(flags);
- val = readl(VA_LEDS_BASE);
-
- switch (ledevt) {
- case led_idle_start:
- val = val & ~VERSATILE_SYS_LED0;
- break;
-
- case led_idle_end:
- val = val | VERSATILE_SYS_LED0;
- break;
-
- case led_timer:
- val = val ^ VERSATILE_SYS_LED1;
- break;
-
- case led_halted:
- val = 0;
- break;
-
- default:
- break;
- }
-
- writel(val, VA_LEDS_BASE);
- local_irq_restore(flags);
-}
-#endif /* CONFIG_LEDS */
-
void versatile_restart(enum reboot_mode mode, const char *cmd)
{
void __iomem *sys = __io_address(VERSATILE_SYS_BASE);
diff --git a/arch/arm/mach-zynq/Kconfig b/arch/arm/mach-zynq/Kconfig
index aaa5162c1509..78e5e007f52d 100644
--- a/arch/arm/mach-zynq/Kconfig
+++ b/arch/arm/mach-zynq/Kconfig
@@ -9,6 +9,8 @@ config ARCH_ZYNQ
select HAVE_ARM_TWD if SMP
select ICST
select MFD_SYSCON
+ select PINCTRL
+ select PINCTRL_ZYNQ
select SOC_BUS
help
Support for Xilinx Zynq ARM Cortex A9 Platform
diff --git a/arch/arm/mach-zynq/common.c b/arch/arm/mach-zynq/common.c
index 26f92c28d22b..c887196cfdbe 100644
--- a/arch/arm/mach-zynq/common.c
+++ b/arch/arm/mach-zynq/common.c
@@ -146,8 +146,6 @@ out:
platform_device_register(&zynq_cpuidle_device);
platform_device_register_full(&devinfo);
-
- zynq_slcr_init();
}
static void __init zynq_timer_init(void)
diff --git a/arch/arm/mach-zynq/pm.c b/arch/arm/mach-zynq/pm.c
index 911fcf865be8..fa44fc1b6dd5 100644
--- a/arch/arm/mach-zynq/pm.c
+++ b/arch/arm/mach-zynq/pm.c
@@ -61,7 +61,7 @@ static void __iomem *zynq_pm_ioremap(const char *comp)
/**
* zynq_pm_late_init() - Power management init
*
- * Initialization of power management related featurs and infrastructure.
+ * Initialization of power management related features and infrastructure.
*/
void __init zynq_pm_late_init(void)
{
diff --git a/arch/arm/mach-zynq/slcr.c b/arch/arm/mach-zynq/slcr.c
index d4cb50cf97c0..c3c24fd8b306 100644
--- a/arch/arm/mach-zynq/slcr.c
+++ b/arch/arm/mach-zynq/slcr.c
@@ -47,11 +47,6 @@ static struct regmap *zynq_slcr_regmap;
*/
static int zynq_slcr_write(u32 val, u32 offset)
{
- if (!zynq_slcr_regmap) {
- writel(val, zynq_slcr_base + offset);
- return 0;
- }
-
return regmap_write(zynq_slcr_regmap, offset, val);
}
@@ -65,12 +60,7 @@ static int zynq_slcr_write(u32 val, u32 offset)
*/
static int zynq_slcr_read(u32 *val, u32 offset)
{
- if (zynq_slcr_regmap)
- return regmap_read(zynq_slcr_regmap, offset, val);
-
- *val = readl(zynq_slcr_base + offset);
-
- return 0;
+ return regmap_read(zynq_slcr_regmap, offset, val);
}
/**
@@ -196,23 +186,6 @@ void zynq_slcr_cpu_state_write(int cpu, bool die)
}
/**
- * zynq_slcr_init - Regular slcr driver init
- * Return: 0 on success, negative errno otherwise.
- *
- * Called early during boot from platform code to remap SLCR area.
- */
-int __init zynq_slcr_init(void)
-{
- zynq_slcr_regmap = syscon_regmap_lookup_by_compatible("xlnx,zynq-slcr");
- if (IS_ERR(zynq_slcr_regmap)) {
- pr_err("%s: failed to find zynq-slcr\n", __func__);
- return -ENODEV;
- }
-
- return 0;
-}
-
-/**
* zynq_early_slcr_init - Early slcr init function
*
* Return: 0 on success, negative errno otherwise.
@@ -237,6 +210,12 @@ int __init zynq_early_slcr_init(void)
np->data = (__force void *)zynq_slcr_base;
+ zynq_slcr_regmap = syscon_regmap_lookup_by_compatible("xlnx,zynq-slcr");
+ if (IS_ERR(zynq_slcr_regmap)) {
+ pr_err("%s: failed to find zynq-slcr\n", __func__);
+ return -ENODEV;
+ }
+
/* unlock the SLCR so that registers can be changed */
zynq_slcr_unlock();
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 03823e784f63..c43c71455566 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -1012,6 +1012,7 @@ config ARCH_SUPPORTS_BIG_ENDIAN
config ARM_KERNMEM_PERMS
bool "Restrict kernel memory permissions"
+ depends on MMU
help
If this is set, kernel memory other than kernel text (and rodata)
will be made non-executable. The tradeoff is that each region is
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
index 5e65ca8dea62..c6c7696b8db9 100644
--- a/arch/arm/mm/cache-l2x0.c
+++ b/arch/arm/mm/cache-l2x0.c
@@ -1,5 +1,5 @@
/*
- * arch/arm/mm/cache-l2x0.c - L210/L220 cache controller support
+ * arch/arm/mm/cache-l2x0.c - L210/L220/L310 cache controller support
*
* Copyright (C) 2007 ARM Limited
*
@@ -41,12 +41,14 @@ struct l2c_init_data {
void (*enable)(void __iomem *, u32, unsigned);
void (*fixup)(void __iomem *, u32, struct outer_cache_fns *);
void (*save)(void __iomem *);
+ void (*configure)(void __iomem *);
struct outer_cache_fns outer_cache;
};
#define CACHE_LINE_SIZE 32
static void __iomem *l2x0_base;
+static const struct l2c_init_data *l2x0_data;
static DEFINE_RAW_SPINLOCK(l2x0_lock);
static u32 l2x0_way_mask; /* Bitmask of active ways */
static u32 l2x0_size;
@@ -106,6 +108,19 @@ static inline void l2c_unlock(void __iomem *base, unsigned num)
}
}
+static void l2c_configure(void __iomem *base)
+{
+ if (outer_cache.configure) {
+ outer_cache.configure(&l2x0_saved_regs);
+ return;
+ }
+
+ if (l2x0_data->configure)
+ l2x0_data->configure(base);
+
+ l2c_write_sec(l2x0_saved_regs.aux_ctrl, base, L2X0_AUX_CTRL);
+}
+
/*
* Enable the L2 cache controller. This function must only be
* called when the cache controller is known to be disabled.
@@ -114,7 +129,12 @@ static void l2c_enable(void __iomem *base, u32 aux, unsigned num_lock)
{
unsigned long flags;
- l2c_write_sec(aux, base, L2X0_AUX_CTRL);
+ /* Do not touch the controller if already enabled. */
+ if (readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN)
+ return;
+
+ l2x0_saved_regs.aux_ctrl = aux;
+ l2c_configure(base);
l2c_unlock(base, num_lock);
@@ -136,76 +156,14 @@ static void l2c_disable(void)
dsb(st);
}
-#ifdef CONFIG_CACHE_PL310
-static inline void cache_wait(void __iomem *reg, unsigned long mask)
-{
- /* cache operations by line are atomic on PL310 */
-}
-#else
-#define cache_wait l2c_wait_mask
-#endif
-
-static inline void cache_sync(void)
-{
- void __iomem *base = l2x0_base;
-
- writel_relaxed(0, base + sync_reg_offset);
- cache_wait(base + L2X0_CACHE_SYNC, 1);
-}
-
-#if defined(CONFIG_PL310_ERRATA_588369) || defined(CONFIG_PL310_ERRATA_727915)
-static inline void debug_writel(unsigned long val)
-{
- l2c_set_debug(l2x0_base, val);
-}
-#else
-/* Optimised out for non-errata case */
-static inline void debug_writel(unsigned long val)
-{
-}
-#endif
-
-static void l2x0_cache_sync(void)
-{
- unsigned long flags;
-
- raw_spin_lock_irqsave(&l2x0_lock, flags);
- cache_sync();
- raw_spin_unlock_irqrestore(&l2x0_lock, flags);
-}
-
-static void __l2x0_flush_all(void)
-{
- debug_writel(0x03);
- __l2c_op_way(l2x0_base + L2X0_CLEAN_INV_WAY);
- cache_sync();
- debug_writel(0x00);
-}
-
-static void l2x0_flush_all(void)
-{
- unsigned long flags;
-
- /* clean all ways */
- raw_spin_lock_irqsave(&l2x0_lock, flags);
- __l2x0_flush_all();
- raw_spin_unlock_irqrestore(&l2x0_lock, flags);
-}
-
-static void l2x0_disable(void)
+static void l2c_save(void __iomem *base)
{
- unsigned long flags;
-
- raw_spin_lock_irqsave(&l2x0_lock, flags);
- __l2x0_flush_all();
- l2c_write_sec(0, l2x0_base, L2X0_CTRL);
- dsb(st);
- raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+ l2x0_saved_regs.aux_ctrl = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
}
-static void l2c_save(void __iomem *base)
+static void l2c_resume(void)
{
- l2x0_saved_regs.aux_ctrl = readl_relaxed(l2x0_base + L2X0_AUX_CTRL);
+ l2c_enable(l2x0_base, l2x0_saved_regs.aux_ctrl, l2x0_data->num_lock);
}
/*
@@ -288,14 +246,6 @@ static void l2c210_sync(void)
__l2c210_cache_sync(l2x0_base);
}
-static void l2c210_resume(void)
-{
- void __iomem *base = l2x0_base;
-
- if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN))
- l2c_enable(base, l2x0_saved_regs.aux_ctrl, 1);
-}
-
static const struct l2c_init_data l2c210_data __initconst = {
.type = "L2C-210",
.way_size_0 = SZ_8K,
@@ -309,7 +259,7 @@ static const struct l2c_init_data l2c210_data __initconst = {
.flush_all = l2c210_flush_all,
.disable = l2c_disable,
.sync = l2c210_sync,
- .resume = l2c210_resume,
+ .resume = l2c_resume,
},
};
@@ -466,7 +416,7 @@ static const struct l2c_init_data l2c220_data = {
.flush_all = l2c220_flush_all,
.disable = l2c_disable,
.sync = l2c220_sync,
- .resume = l2c210_resume,
+ .resume = l2c_resume,
},
};
@@ -615,39 +565,29 @@ static void __init l2c310_save(void __iomem *base)
L310_POWER_CTRL);
}
-static void l2c310_resume(void)
+static void l2c310_configure(void __iomem *base)
{
- void __iomem *base = l2x0_base;
+ unsigned revision;
- if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN)) {
- unsigned revision;
-
- /* restore pl310 setup */
- writel_relaxed(l2x0_saved_regs.tag_latency,
- base + L310_TAG_LATENCY_CTRL);
- writel_relaxed(l2x0_saved_regs.data_latency,
- base + L310_DATA_LATENCY_CTRL);
- writel_relaxed(l2x0_saved_regs.filter_end,
- base + L310_ADDR_FILTER_END);
- writel_relaxed(l2x0_saved_regs.filter_start,
- base + L310_ADDR_FILTER_START);
-
- revision = readl_relaxed(base + L2X0_CACHE_ID) &
- L2X0_CACHE_ID_RTL_MASK;
-
- if (revision >= L310_CACHE_ID_RTL_R2P0)
- l2c_write_sec(l2x0_saved_regs.prefetch_ctrl, base,
- L310_PREFETCH_CTRL);
- if (revision >= L310_CACHE_ID_RTL_R3P0)
- l2c_write_sec(l2x0_saved_regs.pwr_ctrl, base,
- L310_POWER_CTRL);
-
- l2c_enable(base, l2x0_saved_regs.aux_ctrl, 8);
-
- /* Re-enable full-line-of-zeros for Cortex-A9 */
- if (l2x0_saved_regs.aux_ctrl & L310_AUX_CTRL_FULL_LINE_ZERO)
- set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
- }
+ /* restore pl310 setup */
+ l2c_write_sec(l2x0_saved_regs.tag_latency, base,
+ L310_TAG_LATENCY_CTRL);
+ l2c_write_sec(l2x0_saved_regs.data_latency, base,
+ L310_DATA_LATENCY_CTRL);
+ l2c_write_sec(l2x0_saved_regs.filter_end, base,
+ L310_ADDR_FILTER_END);
+ l2c_write_sec(l2x0_saved_regs.filter_start, base,
+ L310_ADDR_FILTER_START);
+
+ revision = readl_relaxed(base + L2X0_CACHE_ID) &
+ L2X0_CACHE_ID_RTL_MASK;
+
+ if (revision >= L310_CACHE_ID_RTL_R2P0)
+ l2c_write_sec(l2x0_saved_regs.prefetch_ctrl, base,
+ L310_PREFETCH_CTRL);
+ if (revision >= L310_CACHE_ID_RTL_R3P0)
+ l2c_write_sec(l2x0_saved_regs.pwr_ctrl, base,
+ L310_POWER_CTRL);
}
static int l2c310_cpu_enable_flz(struct notifier_block *nb, unsigned long act, void *data)
@@ -699,6 +639,23 @@ static void __init l2c310_enable(void __iomem *base, u32 aux, unsigned num_lock)
aux &= ~(L310_AUX_CTRL_FULL_LINE_ZERO | L310_AUX_CTRL_EARLY_BRESP);
}
+ /* r3p0 or later has power control register */
+ if (rev >= L310_CACHE_ID_RTL_R3P0)
+ l2x0_saved_regs.pwr_ctrl = L310_DYNAMIC_CLK_GATING_EN |
+ L310_STNDBY_MODE_EN;
+
+ /*
+ * Always enable non-secure access to the lockdown registers -
+ * we write to them as part of the L2C enable sequence so they
+ * need to be accessible.
+ */
+ aux |= L310_AUX_CTRL_NS_LOCKDOWN;
+
+ l2c_enable(base, aux, num_lock);
+
+ /* Read back resulting AUX_CTRL value as it could have been altered. */
+ aux = readl_relaxed(base + L2X0_AUX_CTRL);
+
if (aux & (L310_AUX_CTRL_DATA_PREFETCH | L310_AUX_CTRL_INSTR_PREFETCH)) {
u32 prefetch = readl_relaxed(base + L310_PREFETCH_CTRL);
@@ -712,23 +669,12 @@ static void __init l2c310_enable(void __iomem *base, u32 aux, unsigned num_lock)
if (rev >= L310_CACHE_ID_RTL_R3P0) {
u32 power_ctrl;
- l2c_write_sec(L310_DYNAMIC_CLK_GATING_EN | L310_STNDBY_MODE_EN,
- base, L310_POWER_CTRL);
power_ctrl = readl_relaxed(base + L310_POWER_CTRL);
pr_info("L2C-310 dynamic clock gating %sabled, standby mode %sabled\n",
power_ctrl & L310_DYNAMIC_CLK_GATING_EN ? "en" : "dis",
power_ctrl & L310_STNDBY_MODE_EN ? "en" : "dis");
}
- /*
- * Always enable non-secure access to the lockdown registers -
- * we write to them as part of the L2C enable sequence so they
- * need to be accessible.
- */
- aux |= L310_AUX_CTRL_NS_LOCKDOWN;
-
- l2c_enable(base, aux, num_lock);
-
if (aux & L310_AUX_CTRL_FULL_LINE_ZERO) {
set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
cpu_notifier(l2c310_cpu_enable_flz, 0);
@@ -760,11 +706,11 @@ static void __init l2c310_fixup(void __iomem *base, u32 cache_id,
if (revision >= L310_CACHE_ID_RTL_R3P0 &&
revision < L310_CACHE_ID_RTL_R3P2) {
- u32 val = readl_relaxed(base + L310_PREFETCH_CTRL);
+ u32 val = l2x0_saved_regs.prefetch_ctrl;
/* I don't think bit23 is required here... but iMX6 does so */
if (val & (BIT(30) | BIT(23))) {
val &= ~(BIT(30) | BIT(23));
- l2c_write_sec(val, base, L310_PREFETCH_CTRL);
+ l2x0_saved_regs.prefetch_ctrl = val;
errata[n++] = "752271";
}
}
@@ -800,6 +746,15 @@ static void l2c310_disable(void)
l2c_disable();
}
+static void l2c310_resume(void)
+{
+ l2c_resume();
+
+ /* Re-enable full-line-of-zeros for Cortex-A9 */
+ if (l2x0_saved_regs.aux_ctrl & L310_AUX_CTRL_FULL_LINE_ZERO)
+ set_auxcr(get_auxcr() | BIT(3) | BIT(2) | BIT(1));
+}
+
static const struct l2c_init_data l2c310_init_fns __initconst = {
.type = "L2C-310",
.way_size_0 = SZ_8K,
@@ -807,6 +762,7 @@ static const struct l2c_init_data l2c310_init_fns __initconst = {
.enable = l2c310_enable,
.fixup = l2c310_fixup,
.save = l2c310_save,
+ .configure = l2c310_configure,
.outer_cache = {
.inv_range = l2c210_inv_range,
.clean_range = l2c210_clean_range,
@@ -818,14 +774,22 @@ static const struct l2c_init_data l2c310_init_fns __initconst = {
},
};
-static void __init __l2c_init(const struct l2c_init_data *data,
- u32 aux_val, u32 aux_mask, u32 cache_id)
+static int __init __l2c_init(const struct l2c_init_data *data,
+ u32 aux_val, u32 aux_mask, u32 cache_id)
{
struct outer_cache_fns fns;
unsigned way_size_bits, ways;
u32 aux, old_aux;
/*
+ * Save the pointer globally so that callbacks which do not receive
+ * context from callers can access the structure.
+ */
+ l2x0_data = kmemdup(data, sizeof(*data), GFP_KERNEL);
+ if (!l2x0_data)
+ return -ENOMEM;
+
+ /*
* Sanity check the aux values. aux_mask is the bits we preserve
* from reading the hardware register, and aux_val is the bits we
* set.
@@ -884,6 +848,7 @@ static void __init __l2c_init(const struct l2c_init_data *data,
fns = data->outer_cache;
fns.write_sec = outer_cache.write_sec;
+ fns.configure = outer_cache.configure;
if (data->fixup)
data->fixup(l2x0_base, cache_id, &fns);
@@ -910,6 +875,8 @@ static void __init __l2c_init(const struct l2c_init_data *data,
data->type, ways, l2x0_size >> 10);
pr_info("%s: CACHE_ID 0x%08x, AUX_CTRL 0x%08x\n",
data->type, cache_id, aux);
+
+ return 0;
}
void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
@@ -936,6 +903,10 @@ void __init l2x0_init(void __iomem *base, u32 aux_val, u32 aux_mask)
break;
}
+ /* Read back current (default) hardware configuration */
+ if (data->save)
+ data->save(l2x0_base);
+
__l2c_init(data, aux_val, aux_mask, cache_id);
}
@@ -979,7 +950,7 @@ static int __init l2x0_cache_size_of_parse(const struct device_node *np,
/* All these l2 caches have the same line = block size actually */
if (!line_size) {
if (block_size) {
- /* If linesize if not given, it is equal to blocksize */
+ /* If linesize is not given, it is equal to blocksize */
line_size = block_size;
} else {
/* Fall back to known size */
@@ -1102,7 +1073,7 @@ static const struct l2c_init_data of_l2c210_data __initconst = {
.flush_all = l2c210_flush_all,
.disable = l2c_disable,
.sync = l2c210_sync,
- .resume = l2c210_resume,
+ .resume = l2c_resume,
},
};
@@ -1120,7 +1091,7 @@ static const struct l2c_init_data of_l2c220_data __initconst = {
.flush_all = l2c220_flush_all,
.disable = l2c_disable,
.sync = l2c220_sync,
- .resume = l2c210_resume,
+ .resume = l2c_resume,
},
};
@@ -1131,32 +1102,32 @@ static void __init l2c310_of_parse(const struct device_node *np,
u32 tag[3] = { 0, 0, 0 };
u32 filter[2] = { 0, 0 };
u32 assoc;
+ u32 prefetch;
+ u32 val;
int ret;
of_property_read_u32_array(np, "arm,tag-latency", tag, ARRAY_SIZE(tag));
if (tag[0] && tag[1] && tag[2])
- writel_relaxed(
+ l2x0_saved_regs.tag_latency =
L310_LATENCY_CTRL_RD(tag[0] - 1) |
L310_LATENCY_CTRL_WR(tag[1] - 1) |
- L310_LATENCY_CTRL_SETUP(tag[2] - 1),
- l2x0_base + L310_TAG_LATENCY_CTRL);
+ L310_LATENCY_CTRL_SETUP(tag[2] - 1);
of_property_read_u32_array(np, "arm,data-latency",
data, ARRAY_SIZE(data));
if (data[0] && data[1] && data[2])
- writel_relaxed(
+ l2x0_saved_regs.data_latency =
L310_LATENCY_CTRL_RD(data[0] - 1) |
L310_LATENCY_CTRL_WR(data[1] - 1) |
- L310_LATENCY_CTRL_SETUP(data[2] - 1),
- l2x0_base + L310_DATA_LATENCY_CTRL);
+ L310_LATENCY_CTRL_SETUP(data[2] - 1);
of_property_read_u32_array(np, "arm,filter-ranges",
filter, ARRAY_SIZE(filter));
if (filter[1]) {
- writel_relaxed(ALIGN(filter[0] + filter[1], SZ_1M),
- l2x0_base + L310_ADDR_FILTER_END);
- writel_relaxed((filter[0] & ~(SZ_1M - 1)) | L310_ADDR_FILTER_EN,
- l2x0_base + L310_ADDR_FILTER_START);
+ l2x0_saved_regs.filter_end =
+ ALIGN(filter[0] + filter[1], SZ_1M);
+ l2x0_saved_regs.filter_start = (filter[0] & ~(SZ_1M - 1))
+ | L310_ADDR_FILTER_EN;
}
ret = l2x0_cache_size_of_parse(np, aux_val, aux_mask, &assoc, SZ_512K);
@@ -1178,6 +1149,58 @@ static void __init l2c310_of_parse(const struct device_node *np,
assoc);
break;
}
+
+ prefetch = l2x0_saved_regs.prefetch_ctrl;
+
+ ret = of_property_read_u32(np, "arm,double-linefill", &val);
+ if (ret == 0) {
+ if (val)
+ prefetch |= L310_PREFETCH_CTRL_DBL_LINEFILL;
+ else
+ prefetch &= ~L310_PREFETCH_CTRL_DBL_LINEFILL;
+ } else if (ret != -EINVAL) {
+ pr_err("L2C-310 OF arm,double-linefill property value is missing\n");
+ }
+
+ ret = of_property_read_u32(np, "arm,double-linefill-incr", &val);
+ if (ret == 0) {
+ if (val)
+ prefetch |= L310_PREFETCH_CTRL_DBL_LINEFILL_INCR;
+ else
+ prefetch &= ~L310_PREFETCH_CTRL_DBL_LINEFILL_INCR;
+ } else if (ret != -EINVAL) {
+ pr_err("L2C-310 OF arm,double-linefill-incr property value is missing\n");
+ }
+
+ ret = of_property_read_u32(np, "arm,double-linefill-wrap", &val);
+ if (ret == 0) {
+ if (!val)
+ prefetch |= L310_PREFETCH_CTRL_DBL_LINEFILL_WRAP;
+ else
+ prefetch &= ~L310_PREFETCH_CTRL_DBL_LINEFILL_WRAP;
+ } else if (ret != -EINVAL) {
+ pr_err("L2C-310 OF arm,double-linefill-wrap property value is missing\n");
+ }
+
+ ret = of_property_read_u32(np, "arm,prefetch-drop", &val);
+ if (ret == 0) {
+ if (val)
+ prefetch |= L310_PREFETCH_CTRL_PREFETCH_DROP;
+ else
+ prefetch &= ~L310_PREFETCH_CTRL_PREFETCH_DROP;
+ } else if (ret != -EINVAL) {
+ pr_err("L2C-310 OF arm,prefetch-drop property value is missing\n");
+ }
+
+ ret = of_property_read_u32(np, "arm,prefetch-offset", &val);
+ if (ret == 0) {
+ prefetch &= ~L310_PREFETCH_CTRL_OFFSET_MASK;
+ prefetch |= val & L310_PREFETCH_CTRL_OFFSET_MASK;
+ } else if (ret != -EINVAL) {
+ pr_err("L2C-310 OF arm,prefetch-offset property value is missing\n");
+ }
+
+ l2x0_saved_regs.prefetch_ctrl = prefetch;
}
static const struct l2c_init_data of_l2c310_data __initconst = {
@@ -1188,6 +1211,7 @@ static const struct l2c_init_data of_l2c310_data __initconst = {
.enable = l2c310_enable,
.fixup = l2c310_fixup,
.save = l2c310_save,
+ .configure = l2c310_configure,
.outer_cache = {
.inv_range = l2c210_inv_range,
.clean_range = l2c210_clean_range,
@@ -1216,6 +1240,7 @@ static const struct l2c_init_data of_l2c310_coherent_data __initconst = {
.enable = l2c310_enable,
.fixup = l2c310_fixup,
.save = l2c310_save,
+ .configure = l2c310_configure,
.outer_cache = {
.inv_range = l2c210_inv_range,
.clean_range = l2c210_clean_range,
@@ -1231,7 +1256,7 @@ static const struct l2c_init_data of_l2c310_coherent_data __initconst = {
* noninclusive, while the hardware cache range operations use
* inclusive start and end addresses.
*/
-static unsigned long calc_range_end(unsigned long start, unsigned long end)
+static unsigned long aurora_range_end(unsigned long start, unsigned long end)
{
/*
* Limit the number of cache lines processed at once,
@@ -1250,25 +1275,13 @@ static unsigned long calc_range_end(unsigned long start, unsigned long end)
return end;
}
-/*
- * Make sure 'start' and 'end' reference the same page, as L2 is PIPT
- * and range operations only do a TLB lookup on the start address.
- */
static void aurora_pa_range(unsigned long start, unsigned long end,
- unsigned long offset)
+ unsigned long offset)
{
+ void __iomem *base = l2x0_base;
+ unsigned long range_end;
unsigned long flags;
- raw_spin_lock_irqsave(&l2x0_lock, flags);
- writel_relaxed(start, l2x0_base + AURORA_RANGE_BASE_ADDR_REG);
- writel_relaxed(end, l2x0_base + offset);
- raw_spin_unlock_irqrestore(&l2x0_lock, flags);
-
- cache_sync();
-}
-
-static void aurora_inv_range(unsigned long start, unsigned long end)
-{
/*
* round start and end adresses up to cache line size
*/
@@ -1276,15 +1289,24 @@ static void aurora_inv_range(unsigned long start, unsigned long end)
end = ALIGN(end, CACHE_LINE_SIZE);
/*
- * Invalidate all full cache lines between 'start' and 'end'.
+ * perform operation on all full cache lines between 'start' and 'end'
*/
while (start < end) {
- unsigned long range_end = calc_range_end(start, end);
- aurora_pa_range(start, range_end - CACHE_LINE_SIZE,
- AURORA_INVAL_RANGE_REG);
+ range_end = aurora_range_end(start, end);
+
+ raw_spin_lock_irqsave(&l2x0_lock, flags);
+ writel_relaxed(start, base + AURORA_RANGE_BASE_ADDR_REG);
+ writel_relaxed(range_end - CACHE_LINE_SIZE, base + offset);
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+
+ writel_relaxed(0, base + AURORA_SYNC_REG);
start = range_end;
}
}
+static void aurora_inv_range(unsigned long start, unsigned long end)
+{
+ aurora_pa_range(start, end, AURORA_INVAL_RANGE_REG);
+}
static void aurora_clean_range(unsigned long start, unsigned long end)
{
@@ -1292,52 +1314,53 @@ static void aurora_clean_range(unsigned long start, unsigned long end)
* If L2 is forced to WT, the L2 will always be clean and we
* don't need to do anything here.
*/
- if (!l2_wt_override) {
- start &= ~(CACHE_LINE_SIZE - 1);
- end = ALIGN(end, CACHE_LINE_SIZE);
- while (start != end) {
- unsigned long range_end = calc_range_end(start, end);
- aurora_pa_range(start, range_end - CACHE_LINE_SIZE,
- AURORA_CLEAN_RANGE_REG);
- start = range_end;
- }
- }
+ if (!l2_wt_override)
+ aurora_pa_range(start, end, AURORA_CLEAN_RANGE_REG);
}
static void aurora_flush_range(unsigned long start, unsigned long end)
{
- start &= ~(CACHE_LINE_SIZE - 1);
- end = ALIGN(end, CACHE_LINE_SIZE);
- while (start != end) {
- unsigned long range_end = calc_range_end(start, end);
- /*
- * If L2 is forced to WT, the L2 will always be clean and we
- * just need to invalidate.
- */
- if (l2_wt_override)
- aurora_pa_range(start, range_end - CACHE_LINE_SIZE,
- AURORA_INVAL_RANGE_REG);
- else
- aurora_pa_range(start, range_end - CACHE_LINE_SIZE,
- AURORA_FLUSH_RANGE_REG);
- start = range_end;
- }
+ if (l2_wt_override)
+ aurora_pa_range(start, end, AURORA_INVAL_RANGE_REG);
+ else
+ aurora_pa_range(start, end, AURORA_FLUSH_RANGE_REG);
}
-static void aurora_save(void __iomem *base)
+static void aurora_flush_all(void)
{
- l2x0_saved_regs.ctrl = readl_relaxed(base + L2X0_CTRL);
- l2x0_saved_regs.aux_ctrl = readl_relaxed(base + L2X0_AUX_CTRL);
+ void __iomem *base = l2x0_base;
+ unsigned long flags;
+
+ /* clean all ways */
+ raw_spin_lock_irqsave(&l2x0_lock, flags);
+ __l2c_op_way(base + L2X0_CLEAN_INV_WAY);
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+
+ writel_relaxed(0, base + AURORA_SYNC_REG);
}
-static void aurora_resume(void)
+static void aurora_cache_sync(void)
+{
+ writel_relaxed(0, l2x0_base + AURORA_SYNC_REG);
+}
+
+static void aurora_disable(void)
{
void __iomem *base = l2x0_base;
+ unsigned long flags;
- if (!(readl(base + L2X0_CTRL) & L2X0_CTRL_EN)) {
- writel_relaxed(l2x0_saved_regs.aux_ctrl, base + L2X0_AUX_CTRL);
- writel_relaxed(l2x0_saved_regs.ctrl, base + L2X0_CTRL);
- }
+ raw_spin_lock_irqsave(&l2x0_lock, flags);
+ __l2c_op_way(base + L2X0_CLEAN_INV_WAY);
+ writel_relaxed(0, base + AURORA_SYNC_REG);
+ l2c_write_sec(0, base, L2X0_CTRL);
+ dsb(st);
+ raw_spin_unlock_irqrestore(&l2x0_lock, flags);
+}
+
+static void aurora_save(void __iomem *base)
+{
+ l2x0_saved_regs.ctrl = readl_relaxed(base + L2X0_CTRL);
+ l2x0_saved_regs.aux_ctrl = readl_relaxed(base + L2X0_AUX_CTRL);
}
/*
@@ -1398,10 +1421,10 @@ static const struct l2c_init_data of_aurora_with_outer_data __initconst = {
.inv_range = aurora_inv_range,
.clean_range = aurora_clean_range,
.flush_range = aurora_flush_range,
- .flush_all = l2x0_flush_all,
- .disable = l2x0_disable,
- .sync = l2x0_cache_sync,
- .resume = aurora_resume,
+ .flush_all = aurora_flush_all,
+ .disable = aurora_disable,
+ .sync = aurora_cache_sync,
+ .resume = l2c_resume,
},
};
@@ -1414,7 +1437,7 @@ static const struct l2c_init_data of_aurora_no_outer_data __initconst = {
.fixup = aurora_fixup,
.save = aurora_save,
.outer_cache = {
- .resume = aurora_resume,
+ .resume = l2c_resume,
},
};
@@ -1562,6 +1585,7 @@ static const struct l2c_init_data of_bcm_l2x0_data __initconst = {
.of_parse = l2c310_of_parse,
.enable = l2c310_enable,
.save = l2c310_save,
+ .configure = l2c310_configure,
.outer_cache = {
.inv_range = bcm_inv_range,
.clean_range = bcm_clean_range,
@@ -1583,18 +1607,12 @@ static void __init tauros3_save(void __iomem *base)
readl_relaxed(base + L310_PREFETCH_CTRL);
}
-static void tauros3_resume(void)
+static void tauros3_configure(void __iomem *base)
{
- void __iomem *base = l2x0_base;
-
- if (!(readl_relaxed(base + L2X0_CTRL) & L2X0_CTRL_EN)) {
- writel_relaxed(l2x0_saved_regs.aux2_ctrl,
- base + TAUROS3_AUX2_CTRL);
- writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
- base + L310_PREFETCH_CTRL);
-
- l2c_enable(base, l2x0_saved_regs.aux_ctrl, 8);
- }
+ writel_relaxed(l2x0_saved_regs.aux2_ctrl,
+ base + TAUROS3_AUX2_CTRL);
+ writel_relaxed(l2x0_saved_regs.prefetch_ctrl,
+ base + L310_PREFETCH_CTRL);
}
static const struct l2c_init_data of_tauros3_data __initconst = {
@@ -1603,9 +1621,10 @@ static const struct l2c_init_data of_tauros3_data __initconst = {
.num_lock = 8,
.enable = l2c_enable,
.save = tauros3_save,
+ .configure = tauros3_configure,
/* Tauros3 broadcasts L1 cache operations to L2 */
.outer_cache = {
- .resume = tauros3_resume,
+ .resume = l2c_resume,
},
};
@@ -1661,6 +1680,10 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
if (!of_property_read_bool(np, "cache-unified"))
pr_err("L2C: device tree omits to specify unified cache\n");
+ /* Read back current (default) hardware configuration */
+ if (data->save)
+ data->save(l2x0_base);
+
/* L2 configuration can only be changed if the cache is disabled */
if (!(readl_relaxed(l2x0_base + L2X0_CTRL) & L2X0_CTRL_EN))
if (data->of_parse)
@@ -1671,8 +1694,6 @@ int __init l2x0_of_init(u32 aux_val, u32 aux_mask)
else
cache_id = readl_relaxed(l2x0_base + L2X0_CACHE_ID);
- __l2c_init(data, aux_val, aux_mask, cache_id);
-
- return 0;
+ return __l2c_init(data, aux_val, aux_mask, cache_id);
}
#endif
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 91892569710f..845769e41332 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -144,21 +144,17 @@ static void flush_context(unsigned int cpu)
/* Update the list of reserved ASIDs and the ASID bitmap. */
bitmap_clear(asid_map, 0, NUM_USER_ASIDS);
for_each_possible_cpu(i) {
- if (i == cpu) {
- asid = 0;
- } else {
- asid = atomic64_xchg(&per_cpu(active_asids, i), 0);
- /*
- * If this CPU has already been through a
- * rollover, but hasn't run another task in
- * the meantime, we must preserve its reserved
- * ASID, as this is the only trace we have of
- * the process it is still running.
- */
- if (asid == 0)
- asid = per_cpu(reserved_asids, i);
- __set_bit(asid & ~ASID_MASK, asid_map);
- }
+ asid = atomic64_xchg(&per_cpu(active_asids, i), 0);
+ /*
+ * If this CPU has already been through a
+ * rollover, but hasn't run another task in
+ * the meantime, we must preserve its reserved
+ * ASID, as this is the only trace we have of
+ * the process it is still running.
+ */
+ if (asid == 0)
+ asid = per_cpu(reserved_asids, i);
+ __set_bit(asid & ~ASID_MASK, asid_map);
per_cpu(reserved_asids, i) = asid;
}
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
index 7864797609b3..903dba064a03 100644
--- a/arch/arm/mm/dma-mapping.c
+++ b/arch/arm/mm/dma-mapping.c
@@ -1940,13 +1940,32 @@ void arm_iommu_release_mapping(struct dma_iommu_mapping *mapping)
}
EXPORT_SYMBOL_GPL(arm_iommu_release_mapping);
+static int __arm_iommu_attach_device(struct device *dev,
+ struct dma_iommu_mapping *mapping)
+{
+ int err;
+
+ err = iommu_attach_device(mapping->domain, dev);
+ if (err)
+ return err;
+
+ kref_get(&mapping->kref);
+ dev->archdata.mapping = mapping;
+
+ pr_debug("Attached IOMMU controller to %s device.\n", dev_name(dev));
+ return 0;
+}
+
/**
* arm_iommu_attach_device
* @dev: valid struct device pointer
* @mapping: io address space mapping structure (returned from
* arm_iommu_create_mapping)
*
- * Attaches specified io address space mapping to the provided device,
+ * Attaches specified io address space mapping to the provided device.
+ * This replaces the dma operations (dma_map_ops pointer) with the
+ * IOMMU aware version.
+ *
* More than one client might be attached to the same io address space
* mapping.
*/
@@ -1955,25 +1974,16 @@ int arm_iommu_attach_device(struct device *dev,
{
int err;
- err = iommu_attach_device(mapping->domain, dev);
+ err = __arm_iommu_attach_device(dev, mapping);
if (err)
return err;
- kref_get(&mapping->kref);
- dev->archdata.mapping = mapping;
-
- pr_debug("Attached IOMMU controller to %s device.\n", dev_name(dev));
+ set_dma_ops(dev, &iommu_ops);
return 0;
}
EXPORT_SYMBOL_GPL(arm_iommu_attach_device);
-/**
- * arm_iommu_detach_device
- * @dev: valid struct device pointer
- *
- * Detaches the provided device from a previously attached map.
- */
-void arm_iommu_detach_device(struct device *dev)
+static void __arm_iommu_detach_device(struct device *dev)
{
struct dma_iommu_mapping *mapping;
@@ -1989,6 +1999,19 @@ void arm_iommu_detach_device(struct device *dev)
pr_debug("Detached IOMMU controller from %s device.\n", dev_name(dev));
}
+
+/**
+ * arm_iommu_detach_device
+ * @dev: valid struct device pointer
+ *
+ * Detaches the provided device from a previously attached map.
+ * This voids the dma operations (dma_map_ops pointer)
+ */
+void arm_iommu_detach_device(struct device *dev)
+{
+ __arm_iommu_detach_device(dev);
+ set_dma_ops(dev, NULL);
+}
EXPORT_SYMBOL_GPL(arm_iommu_detach_device);
static struct dma_map_ops *arm_get_iommu_dma_map_ops(bool coherent)
@@ -2011,7 +2034,7 @@ static bool arm_setup_iommu_dma_ops(struct device *dev, u64 dma_base, u64 size,
return false;
}
- if (arm_iommu_attach_device(dev, mapping)) {
+ if (__arm_iommu_attach_device(dev, mapping)) {
pr_warn("Failed to attached device %s to IOMMU_mapping\n",
dev_name(dev));
arm_iommu_release_mapping(mapping);
@@ -2025,7 +2048,10 @@ static void arm_teardown_iommu_dma_ops(struct device *dev)
{
struct dma_iommu_mapping *mapping = dev->archdata.mapping;
- arm_iommu_detach_device(dev);
+ if (!mapping)
+ return;
+
+ __arm_iommu_detach_device(dev);
arm_iommu_release_mapping(mapping);
}
diff --git a/arch/arm/mm/hugetlbpage.c b/arch/arm/mm/hugetlbpage.c
index 66781bf34077..c72412415093 100644
--- a/arch/arm/mm/hugetlbpage.c
+++ b/arch/arm/mm/hugetlbpage.c
@@ -36,12 +36,6 @@
* of type casting from pmd_t * to pte_t *.
*/
-struct page *follow_huge_addr(struct mm_struct *mm, unsigned long address,
- int write)
-{
- return ERR_PTR(-EINVAL);
-}
-
int pud_huge(pud_t pud)
{
return 0;
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
index 2495c8cb47ba..1609b022a72f 100644
--- a/arch/arm/mm/init.c
+++ b/arch/arm/mm/init.c
@@ -319,10 +319,7 @@ void __init arm_memblock_init(const struct machine_desc *mdesc)
early_init_fdt_scan_reserved_mem();
- /*
- * reserve memory for DMA contigouos allocations,
- * must come from DMA area inside low memory
- */
+ /* reserve memory for DMA contiguous allocations */
dma_contiguous_reserve(arm_dma_limit);
arm_memblock_steal_permitted = false;
diff --git a/arch/arm/mm/pgd.c b/arch/arm/mm/pgd.c
index 249379535be2..a3681f11dd9f 100644
--- a/arch/arm/mm/pgd.c
+++ b/arch/arm/mm/pgd.c
@@ -97,6 +97,7 @@ pgd_t *pgd_alloc(struct mm_struct *mm)
no_pte:
pmd_free(mm, new_pmd);
+ mm_dec_nr_pmds(mm);
no_pmd:
pud_free(mm, new_pud);
no_pud:
@@ -130,9 +131,11 @@ void pgd_free(struct mm_struct *mm, pgd_t *pgd_base)
pte = pmd_pgtable(*pmd);
pmd_clear(pmd);
pte_free(mm, pte);
+ atomic_long_dec(&mm->nr_ptes);
no_pmd:
pud_clear(pud);
pmd_free(mm, pmd);
+ mm_dec_nr_pmds(mm);
no_pud:
pgd_clear(pgd);
pud_free(mm, pud);
@@ -152,6 +155,7 @@ no_pgd:
pmd = pmd_offset(pud, 0);
pud_clear(pud);
pmd_free(mm, pmd);
+ mm_dec_nr_pmds(mm);
pgd_clear(pgd);
pud_free(mm, pud);
}
diff --git a/arch/arm/mm/proc-macros.S b/arch/arm/mm/proc-macros.S
index ba1196c968d8..082b9f2f7e90 100644
--- a/arch/arm/mm/proc-macros.S
+++ b/arch/arm/mm/proc-macros.S
@@ -98,7 +98,7 @@
#endif
#if !defined (CONFIG_ARM_LPAE) && \
(L_PTE_XN+L_PTE_USER+L_PTE_RDONLY+L_PTE_DIRTY+L_PTE_YOUNG+\
- L_PTE_FILE+L_PTE_PRESENT) > L_PTE_SHARED
+ L_PTE_PRESENT) > L_PTE_SHARED
#error Invalid Linux PTE bit settings
#endif
#endif /* CONFIG_MMU */
diff --git a/arch/arm/plat-iop/pmu.c b/arch/arm/plat-iop/pmu.c
index ad9f9744a82d..c6d979ace524 100644
--- a/arch/arm/plat-iop/pmu.c
+++ b/arch/arm/plat-iop/pmu.c
@@ -24,7 +24,7 @@ static struct resource pmu_resource = {
};
static struct platform_device pmu_device = {
- .name = "arm-pmu",
+ .name = "xscale-pmu",
.id = -1,
.resource = &pmu_resource,
.num_resources = 1,
diff --git a/arch/arm/plat-omap/dma.c b/arch/arm/plat-omap/dma.c
index 24770e5a5081..6416e03b4482 100644
--- a/arch/arm/plat-omap/dma.c
+++ b/arch/arm/plat-omap/dma.c
@@ -151,14 +151,6 @@ static int omap_dma_in_1510_mode(void)
#endif
#ifdef CONFIG_ARCH_OMAP1
-static inline int get_gdma_dev(int req)
-{
- u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
- int shift = ((req - 1) % 5) * 6;
-
- return ((omap_readl(reg) >> shift) & 0x3f) + 1;
-}
-
static inline void set_gdma_dev(int req, int dev)
{
u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig
index 9bd2776e7d05..cb8e3d655d1a 100644
--- a/arch/arm/plat-samsung/Kconfig
+++ b/arch/arm/plat-samsung/Kconfig
@@ -236,13 +236,6 @@ config S3C_SETUP_CAMIF
help
Compile in common setup code for S3C CAMIF devices
-# DMA
-
-config S3C_DMA
- bool
- help
- Internal configuration for S3C DMA core
-
config SAMSUNG_PM_GPIO
bool
default y if GPIO_SAMSUNG && PM
@@ -250,14 +243,6 @@ config SAMSUNG_PM_GPIO
Include legacy GPIO power management code for platforms not using
pinctrl-samsung driver.
-config SAMSUNG_DMADEV
- bool "Use legacy Samsung DMA abstraction"
- depends on CPU_S5PV210 || ARCH_S3C64XX
- select DMADEVICES
- default y
- help
- Use DMA device engine for PL330 DMAC.
-
endif
config S5P_DEV_MFC
diff --git a/arch/arm/plat-samsung/Makefile b/arch/arm/plat-samsung/Makefile
index 87746c37f030..1a29ab1f446d 100644
--- a/arch/arm/plat-samsung/Makefile
+++ b/arch/arm/plat-samsung/Makefile
@@ -26,12 +26,6 @@ obj-$(CONFIG_SAMSUNG_DEV_BACKLIGHT) += dev-backlight.o
obj-$(CONFIG_S3C_SETUP_CAMIF) += setup-camif.o
-# DMA support
-
-obj-$(CONFIG_S3C_DMA) += dma.o s3c-dma-ops.o
-
-obj-$(CONFIG_SAMSUNG_DMADEV) += dma-ops.o
-
# PM support
obj-$(CONFIG_PM_SLEEP) += pm-common.o
diff --git a/arch/arm/plat-samsung/cpu.c b/arch/arm/plat-samsung/cpu.c
index 360618ee39e5..71333bb61013 100644
--- a/arch/arm/plat-samsung/cpu.c
+++ b/arch/arm/plat-samsung/cpu.c
@@ -40,10 +40,14 @@ void __init s3c64xx_init_cpu(void)
}
samsung_cpu_rev = 0;
+
+ pr_info("Samsung CPU ID: 0x%08lx\n", samsung_cpu_id);
}
void __init s5p_init_cpu(void __iomem *cpuid_addr)
{
samsung_cpu_id = __raw_readl(cpuid_addr);
samsung_cpu_rev = samsung_cpu_id & 0xFF;
+
+ pr_info("Samsung CPU ID: 0x%08lx\n", samsung_cpu_id);
}
diff --git a/arch/arm/plat-samsung/dma-ops.c b/arch/arm/plat-samsung/dma-ops.c
deleted file mode 100644
index 886326ee6f6c..000000000000
--- a/arch/arm/plat-samsung/dma-ops.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/* linux/arch/arm/plat-samsung/dma-ops.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Samsung DMA Operations
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/amba/pl330.h>
-#include <linux/scatterlist.h>
-#include <linux/export.h>
-
-#include <mach/dma.h>
-
-#if defined(CONFIG_PL330_DMA)
-#define dma_filter pl330_filter
-#elif defined(CONFIG_S3C64XX_PL080)
-#define dma_filter pl08x_filter_id
-#endif
-
-static unsigned samsung_dmadev_request(enum dma_ch dma_ch,
- struct samsung_dma_req *param,
- struct device *dev, char *ch_name)
-{
- dma_cap_mask_t mask;
-
- dma_cap_zero(mask);
- dma_cap_set(param->cap, mask);
-
- if (dev->of_node)
- return (unsigned)dma_request_slave_channel(dev, ch_name);
- else
- return (unsigned)dma_request_channel(mask, dma_filter,
- (void *)dma_ch);
-}
-
-static int samsung_dmadev_release(unsigned ch, void *param)
-{
- dma_release_channel((struct dma_chan *)ch);
-
- return 0;
-}
-
-static int samsung_dmadev_config(unsigned ch,
- struct samsung_dma_config *param)
-{
- struct dma_chan *chan = (struct dma_chan *)ch;
- struct dma_slave_config slave_config;
-
- if (param->direction == DMA_DEV_TO_MEM) {
- memset(&slave_config, 0, sizeof(struct dma_slave_config));
- slave_config.direction = param->direction;
- slave_config.src_addr = param->fifo;
- slave_config.src_addr_width = param->width;
- slave_config.src_maxburst = 1;
- dmaengine_slave_config(chan, &slave_config);
- } else if (param->direction == DMA_MEM_TO_DEV) {
- memset(&slave_config, 0, sizeof(struct dma_slave_config));
- slave_config.direction = param->direction;
- slave_config.dst_addr = param->fifo;
- slave_config.dst_addr_width = param->width;
- slave_config.dst_maxburst = 1;
- dmaengine_slave_config(chan, &slave_config);
- } else {
- pr_warn("unsupported direction\n");
- return -EINVAL;
- }
-
- return 0;
-}
-
-static int samsung_dmadev_prepare(unsigned ch,
- struct samsung_dma_prep *param)
-{
- struct scatterlist sg;
- struct dma_chan *chan = (struct dma_chan *)ch;
- struct dma_async_tx_descriptor *desc;
-
- switch (param->cap) {
- case DMA_SLAVE:
- sg_init_table(&sg, 1);
- sg_dma_len(&sg) = param->len;
- sg_set_page(&sg, pfn_to_page(PFN_DOWN(param->buf)),
- param->len, offset_in_page(param->buf));
- sg_dma_address(&sg) = param->buf;
-
- desc = dmaengine_prep_slave_sg(chan,
- &sg, 1, param->direction, DMA_PREP_INTERRUPT);
- break;
- case DMA_CYCLIC:
- desc = dmaengine_prep_dma_cyclic(chan, param->buf,
- param->len, param->period, param->direction,
- DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
- break;
- default:
- dev_err(&chan->dev->device, "unsupported format\n");
- return -EFAULT;
- }
-
- if (!desc) {
- dev_err(&chan->dev->device, "cannot prepare cyclic dma\n");
- return -EFAULT;
- }
-
- desc->callback = param->fp;
- desc->callback_param = param->fp_param;
-
- dmaengine_submit((struct dma_async_tx_descriptor *)desc);
-
- return 0;
-}
-
-static inline int samsung_dmadev_trigger(unsigned ch)
-{
- dma_async_issue_pending((struct dma_chan *)ch);
-
- return 0;
-}
-
-static inline int samsung_dmadev_flush(unsigned ch)
-{
- return dmaengine_terminate_all((struct dma_chan *)ch);
-}
-
-static struct samsung_dma_ops dmadev_ops = {
- .request = samsung_dmadev_request,
- .release = samsung_dmadev_release,
- .config = samsung_dmadev_config,
- .prepare = samsung_dmadev_prepare,
- .trigger = samsung_dmadev_trigger,
- .started = NULL,
- .flush = samsung_dmadev_flush,
- .stop = samsung_dmadev_flush,
-};
-
-void *samsung_dmadev_get_ops(void)
-{
- return &dmadev_ops;
-}
-EXPORT_SYMBOL(samsung_dmadev_get_ops);
diff --git a/arch/arm/plat-samsung/dma.c b/arch/arm/plat-samsung/dma.c
deleted file mode 100644
index 6143aa147688..000000000000
--- a/arch/arm/plat-samsung/dma.c
+++ /dev/null
@@ -1,84 +0,0 @@
-/* linux/arch/arm/plat-samsung/dma.c
- *
- * Copyright (c) 2003-2009 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * S3C DMA core
- *
- * 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.
-*/
-
-struct s3c2410_dma_buf;
-
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/errno.h>
-
-#include <mach/dma.h>
-#include <mach/irqs.h>
-
-/* dma channel state information */
-struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
-struct s3c2410_dma_chan *s3c_dma_chan_map[DMACH_MAX];
-
-/* s3c_dma_lookup_channel
- *
- * change the dma channel number given into a real dma channel id
-*/
-
-struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel)
-{
- if (channel & DMACH_LOW_LEVEL)
- return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
- else
- return s3c_dma_chan_map[channel];
-}
-
-/* do we need to protect the settings of the fields from
- * irq?
-*/
-
-int s3c2410_dma_set_opfn(enum dma_ch channel, s3c2410_dma_opfn_t rtn)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
- if (chan == NULL)
- return -EINVAL;
-
- pr_debug("%s: chan=%p, op rtn=%p\n", __func__, chan, rtn);
-
- chan->op_fn = rtn;
-
- return 0;
-}
-EXPORT_SYMBOL(s3c2410_dma_set_opfn);
-
-int s3c2410_dma_set_buffdone_fn(enum dma_ch channel, s3c2410_dma_cbfn_t rtn)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
- if (chan == NULL)
- return -EINVAL;
-
- pr_debug("%s: chan=%p, callback rtn=%p\n", __func__, chan, rtn);
-
- chan->callback_fn = rtn;
-
- return 0;
-}
-EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
-
-int s3c2410_dma_setflags(enum dma_ch channel, unsigned int flags)
-{
- struct s3c2410_dma_chan *chan = s3c_dma_lookup_channel(channel);
-
- if (chan == NULL)
- return -EINVAL;
-
- chan->flags = flags;
- return 0;
-}
-EXPORT_SYMBOL(s3c2410_dma_setflags);
diff --git a/arch/arm/plat-samsung/include/plat/dma-core.h b/arch/arm/plat-samsung/include/plat/dma-core.h
deleted file mode 100644
index 32ff2a92cb3c..000000000000
--- a/arch/arm/plat-samsung/include/plat/dma-core.h
+++ /dev/null
@@ -1,22 +0,0 @@
-/* arch/arm/plat-s3c/include/plat/dma.h
- *
- * Copyright 2008 Openmoko, Inc.
- * Copyright 2008 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- * http://armlinux.simtec.co.uk/
- *
- * Samsung S3C DMA core support
- *
- * 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.
-*/
-
-extern struct s3c2410_dma_chan *s3c_dma_lookup_channel(unsigned int channel);
-
-extern struct s3c2410_dma_chan *s3c_dma_chan_map[];
-
-/* the currently allocated channel information */
-extern struct s3c2410_dma_chan s3c2410_chans[];
-
-
diff --git a/arch/arm/plat-samsung/include/plat/dma-ops.h b/arch/arm/plat-samsung/include/plat/dma-ops.h
deleted file mode 100644
index ce6d7634b6cb..000000000000
--- a/arch/arm/plat-samsung/include/plat/dma-ops.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/* arch/arm/plat-samsung/include/plat/dma-ops.h
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Samsung DMA support
- *
- * 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 __SAMSUNG_DMA_OPS_H_
-#define __SAMSUNG_DMA_OPS_H_ __FILE__
-
-#include <linux/dmaengine.h>
-#include <mach/dma.h>
-
-struct samsung_dma_req {
- enum dma_transaction_type cap;
- struct s3c2410_dma_client *client;
-};
-
-struct samsung_dma_prep {
- enum dma_transaction_type cap;
- enum dma_transfer_direction direction;
- dma_addr_t buf;
- unsigned long period;
- unsigned long len;
- void (*fp)(void *data);
- void *fp_param;
-};
-
-struct samsung_dma_config {
- enum dma_transfer_direction direction;
- enum dma_slave_buswidth width;
- dma_addr_t fifo;
-};
-
-struct samsung_dma_ops {
- unsigned (*request)(enum dma_ch ch, struct samsung_dma_req *param,
- struct device *dev, char *ch_name);
- int (*release)(unsigned ch, void *param);
- int (*config)(unsigned ch, struct samsung_dma_config *param);
- int (*prepare)(unsigned ch, struct samsung_dma_prep *param);
- int (*trigger)(unsigned ch);
- int (*started)(unsigned ch);
- int (*flush)(unsigned ch);
- int (*stop)(unsigned ch);
-};
-
-extern void *samsung_dmadev_get_ops(void);
-extern void *s3c_dma_get_ops(void);
-
-static inline void *__samsung_dma_get_ops(void)
-{
- if (samsung_dma_is_dmadev())
- return samsung_dmadev_get_ops();
- else
- return s3c_dma_get_ops();
-}
-
-/*
- * samsung_dma_get_ops
- * get the set of samsung dma operations
- */
-#define samsung_dma_get_ops() __samsung_dma_get_ops()
-
-#endif /* __SAMSUNG_DMA_OPS_H_ */
diff --git a/arch/arm/plat-samsung/include/plat/dma-pl330.h b/arch/arm/plat-samsung/include/plat/dma-pl330.h
deleted file mode 100644
index abe07fae71db..000000000000
--- a/arch/arm/plat-samsung/include/plat/dma-pl330.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * Copyright (C) 2010 Samsung Electronics Co. Ltd.
- * Jaswinder Singh <jassi.brar@samsung.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 __DMA_PL330_H_
-#define __DMA_PL330_H_ __FILE__
-
-/*
- * PL330 can assign any channel to communicate with
- * any of the peripherals attched to the DMAC.
- * For the sake of consistency across client drivers,
- * We keep the channel names unchanged and only add
- * missing peripherals are added.
- * Order is not important since DMA PL330 API driver
- * use these just as IDs.
- */
-enum dma_ch {
- DMACH_UART0_RX = 0,
- DMACH_UART0_TX,
- DMACH_UART1_RX,
- DMACH_UART1_TX,
- DMACH_UART2_RX,
- DMACH_UART2_TX,
- DMACH_UART3_RX,
- DMACH_UART3_TX,
- DMACH_UART4_RX,
- DMACH_UART4_TX,
- DMACH_UART5_RX,
- DMACH_UART5_TX,
- DMACH_USI_RX,
- DMACH_USI_TX,
- DMACH_IRDA,
- DMACH_I2S0_RX,
- DMACH_I2S0_TX,
- DMACH_I2S0S_TX,
- DMACH_I2S1_RX,
- DMACH_I2S1_TX,
- DMACH_I2S2_RX,
- DMACH_I2S2_TX,
- DMACH_SPI0_RX,
- DMACH_SPI0_TX,
- DMACH_SPI1_RX,
- DMACH_SPI1_TX,
- DMACH_SPI2_RX,
- DMACH_SPI2_TX,
- DMACH_AC97_MICIN,
- DMACH_AC97_PCMIN,
- DMACH_AC97_PCMOUT,
- DMACH_EXTERNAL,
- DMACH_PWM,
- DMACH_SPDIF,
- DMACH_HSI_RX,
- DMACH_HSI_TX,
- DMACH_PCM0_TX,
- DMACH_PCM0_RX,
- DMACH_PCM1_TX,
- DMACH_PCM1_RX,
- DMACH_PCM2_TX,
- DMACH_PCM2_RX,
- DMACH_MSM_REQ3,
- DMACH_MSM_REQ2,
- DMACH_MSM_REQ1,
- DMACH_MSM_REQ0,
- DMACH_SLIMBUS0_RX,
- DMACH_SLIMBUS0_TX,
- DMACH_SLIMBUS0AUX_RX,
- DMACH_SLIMBUS0AUX_TX,
- DMACH_SLIMBUS1_RX,
- DMACH_SLIMBUS1_TX,
- DMACH_SLIMBUS2_RX,
- DMACH_SLIMBUS2_TX,
- DMACH_SLIMBUS3_RX,
- DMACH_SLIMBUS3_TX,
- DMACH_SLIMBUS4_RX,
- DMACH_SLIMBUS4_TX,
- DMACH_SLIMBUS5_RX,
- DMACH_SLIMBUS5_TX,
- DMACH_MIPI_HSI0,
- DMACH_MIPI_HSI1,
- DMACH_MIPI_HSI2,
- DMACH_MIPI_HSI3,
- DMACH_MIPI_HSI4,
- DMACH_MIPI_HSI5,
- DMACH_MIPI_HSI6,
- DMACH_MIPI_HSI7,
- DMACH_DISP1,
- DMACH_MTOM_0,
- DMACH_MTOM_1,
- DMACH_MTOM_2,
- DMACH_MTOM_3,
- DMACH_MTOM_4,
- DMACH_MTOM_5,
- DMACH_MTOM_6,
- DMACH_MTOM_7,
- /* END Marker, also used to denote a reserved channel */
- DMACH_MAX,
-};
-
-struct s3c2410_dma_client {
- char *name;
-};
-
-static inline bool samsung_dma_has_circular(void)
-{
- return true;
-}
-
-static inline bool samsung_dma_is_dmadev(void)
-{
- return true;
-}
-
-#include <plat/dma-ops.h>
-
-#endif /* __DMA_PL330_H_ */
diff --git a/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h b/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
deleted file mode 100644
index bd3a6db14cbb..000000000000
--- a/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* linux/arch/arm/plat-samsung/include/plat/dma-s3c24xx.h
- *
- * Copyright (C) 2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C24XX DMA support - per SoC functions
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#include <plat/dma-core.h>
-
-extern struct bus_type dma_subsys;
-extern struct s3c2410_dma_chan s3c2410_chans[S3C_DMA_CHANNELS];
-
-#define DMA_CH_VALID (1<<31)
-#define DMA_CH_NEVER (1<<30)
-
-/* struct s3c24xx_dma_map
- *
- * this holds the mapping information for the channel selected
- * to be connected to the specified device
-*/
-
-struct s3c24xx_dma_map {
- const char *name;
-
- unsigned long channels[S3C_DMA_CHANNELS];
-};
-
-struct s3c24xx_dma_selection {
- struct s3c24xx_dma_map *map;
- unsigned long map_size;
- unsigned long dcon_mask;
-
- void (*select)(struct s3c2410_dma_chan *chan,
- struct s3c24xx_dma_map *map);
-};
-
-extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
-
-/* struct s3c24xx_dma_order_ch
- *
- * channel map for one of the `enum dma_ch` dma channels. the list
- * entry contains a set of low-level channel numbers, orred with
- * DMA_CH_VALID, which are checked in the order in the array.
-*/
-
-struct s3c24xx_dma_order_ch {
- unsigned int list[S3C_DMA_CHANNELS]; /* list of channels */
- unsigned int flags; /* flags */
-};
-
-/* struct s3c24xx_dma_order
- *
- * information provided by either the core or the board to give the
- * dma system a hint on how to allocate channels
-*/
-
-struct s3c24xx_dma_order {
- struct s3c24xx_dma_order_ch channels[DMACH_MAX];
-};
-
-extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map);
-
-/* DMA init code, called from the cpu support code */
-
-extern int s3c2410_dma_init(void);
-
-extern int s3c24xx_dma_init(unsigned int channels, unsigned int irq,
- unsigned int stride);
diff --git a/arch/arm/plat-samsung/include/plat/dma.h b/arch/arm/plat-samsung/include/plat/dma.h
deleted file mode 100644
index 7b02143ccd9a..000000000000
--- a/arch/arm/plat-samsung/include/plat/dma.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* arch/arm/plat-samsung/include/plat/dma.h
- *
- * Copyright (C) 2003-2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C DMA support
- *
- * 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_DMA_H
-#define __PLAT_DMA_H
-
-#include <linux/dma-mapping.h>
-
-enum s3c2410_dma_buffresult {
- S3C2410_RES_OK,
- S3C2410_RES_ERR,
- S3C2410_RES_ABORT
-};
-
-/* enum s3c2410_chan_op
- *
- * operation codes passed to the DMA code by the user, and also used
- * to inform the current channel owner of any changes to the system state
-*/
-
-enum s3c2410_chan_op {
- S3C2410_DMAOP_START,
- S3C2410_DMAOP_STOP,
- S3C2410_DMAOP_PAUSE,
- S3C2410_DMAOP_RESUME,
- S3C2410_DMAOP_FLUSH,
- S3C2410_DMAOP_TIMEOUT, /* internal signal to handler */
- S3C2410_DMAOP_STARTED, /* indicate channel started */
-};
-
-struct s3c2410_dma_client {
- char *name;
-};
-
-struct s3c2410_dma_chan;
-enum dma_ch;
-
-/* s3c2410_dma_cbfn_t
- *
- * buffer callback routine type
-*/
-
-typedef void (*s3c2410_dma_cbfn_t)(struct s3c2410_dma_chan *,
- void *buf, int size,
- enum s3c2410_dma_buffresult result);
-
-typedef int (*s3c2410_dma_opfn_t)(struct s3c2410_dma_chan *,
- enum s3c2410_chan_op );
-
-
-
-/* s3c2410_dma_request
- *
- * request a dma channel exclusivley
-*/
-
-extern int s3c2410_dma_request(enum dma_ch channel,
- struct s3c2410_dma_client *, void *dev);
-
-
-/* s3c2410_dma_ctrl
- *
- * change the state of the dma channel
-*/
-
-extern int s3c2410_dma_ctrl(enum dma_ch channel, enum s3c2410_chan_op op);
-
-/* s3c2410_dma_setflags
- *
- * set the channel's flags to a given state
-*/
-
-extern int s3c2410_dma_setflags(enum dma_ch channel,
- unsigned int flags);
-
-/* s3c2410_dma_free
- *
- * free the dma channel (will also abort any outstanding operations)
-*/
-
-extern int s3c2410_dma_free(enum dma_ch channel, struct s3c2410_dma_client *);
-
-/* s3c2410_dma_enqueue
- *
- * place the given buffer onto the queue of operations for the channel.
- * The buffer must be allocated from dma coherent memory, or the Dcache/WB
- * drained before the buffer is given to the DMA system.
-*/
-
-extern int s3c2410_dma_enqueue(enum dma_ch channel, void *id,
- dma_addr_t data, int size);
-
-/* s3c2410_dma_config
- *
- * configure the dma channel
-*/
-
-extern int s3c2410_dma_config(enum dma_ch channel, int xferunit);
-
-/* s3c2410_dma_devconfig
- *
- * configure the device we're talking to
-*/
-
-extern int s3c2410_dma_devconfig(enum dma_ch channel,
- enum dma_data_direction source, unsigned long devaddr);
-
-/* s3c2410_dma_getposition
- *
- * get the position that the dma transfer is currently at
-*/
-
-extern int s3c2410_dma_getposition(enum dma_ch channel,
- dma_addr_t *src, dma_addr_t *dest);
-
-extern int s3c2410_dma_set_opfn(enum dma_ch, s3c2410_dma_opfn_t rtn);
-extern int s3c2410_dma_set_buffdone_fn(enum dma_ch, s3c2410_dma_cbfn_t rtn);
-
-#include <plat/dma-ops.h>
-
-#endif
diff --git a/arch/arm/plat-samsung/include/plat/regs-dma.h b/arch/arm/plat-samsung/include/plat/regs-dma.h
deleted file mode 100644
index a7d622ef16af..000000000000
--- a/arch/arm/plat-samsung/include/plat/regs-dma.h
+++ /dev/null
@@ -1,151 +0,0 @@
-/* arch/arm/plat-samsung/include/plat/regs-dma.h
- *
- * Copyright (C) 2003-2006 Simtec Electronics
- * Ben Dooks <ben@simtec.co.uk>
- *
- * Samsung S3C24XX DMA support
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
-*/
-
-#ifndef __ASM_PLAT_REGS_DMA_H
-#define __ASM_PLAT_REGS_DMA_H __FILE__
-
-#define S3C2410_DMA_DISRC (0x00)
-#define S3C2410_DMA_DISRCC (0x04)
-#define S3C2410_DMA_DIDST (0x08)
-#define S3C2410_DMA_DIDSTC (0x0C)
-#define S3C2410_DMA_DCON (0x10)
-#define S3C2410_DMA_DSTAT (0x14)
-#define S3C2410_DMA_DCSRC (0x18)
-#define S3C2410_DMA_DCDST (0x1C)
-#define S3C2410_DMA_DMASKTRIG (0x20)
-#define S3C2412_DMA_DMAREQSEL (0x24)
-#define S3C2443_DMA_DMAREQSEL (0x24)
-
-#define S3C2410_DISRCC_INC (1 << 0)
-#define S3C2410_DISRCC_APB (1 << 1)
-
-#define S3C2410_DMASKTRIG_STOP (1 << 2)
-#define S3C2410_DMASKTRIG_ON (1 << 1)
-#define S3C2410_DMASKTRIG_SWTRIG (1 << 0)
-
-#define S3C2410_DCON_DEMAND (0 << 31)
-#define S3C2410_DCON_HANDSHAKE (1 << 31)
-#define S3C2410_DCON_SYNC_PCLK (0 << 30)
-#define S3C2410_DCON_SYNC_HCLK (1 << 30)
-
-#define S3C2410_DCON_INTREQ (1 << 29)
-
-#define S3C2410_DCON_CH0_XDREQ0 (0 << 24)
-#define S3C2410_DCON_CH0_UART0 (1 << 24)
-#define S3C2410_DCON_CH0_SDI (2 << 24)
-#define S3C2410_DCON_CH0_TIMER (3 << 24)
-#define S3C2410_DCON_CH0_USBEP1 (4 << 24)
-
-#define S3C2410_DCON_CH1_XDREQ1 (0 << 24)
-#define S3C2410_DCON_CH1_UART1 (1 << 24)
-#define S3C2410_DCON_CH1_I2SSDI (2 << 24)
-#define S3C2410_DCON_CH1_SPI (3 << 24)
-#define S3C2410_DCON_CH1_USBEP2 (4 << 24)
-
-#define S3C2410_DCON_CH2_I2SSDO (0 << 24)
-#define S3C2410_DCON_CH2_I2SSDI (1 << 24)
-#define S3C2410_DCON_CH2_SDI (2 << 24)
-#define S3C2410_DCON_CH2_TIMER (3 << 24)
-#define S3C2410_DCON_CH2_USBEP3 (4 << 24)
-
-#define S3C2410_DCON_CH3_UART2 (0 << 24)
-#define S3C2410_DCON_CH3_SDI (1 << 24)
-#define S3C2410_DCON_CH3_SPI (2 << 24)
-#define S3C2410_DCON_CH3_TIMER (3 << 24)
-#define S3C2410_DCON_CH3_USBEP4 (4 << 24)
-
-#define S3C2410_DCON_SRCSHIFT (24)
-#define S3C2410_DCON_SRCMASK (7 << 24)
-
-#define S3C2410_DCON_BYTE (0 << 20)
-#define S3C2410_DCON_HALFWORD (1 << 20)
-#define S3C2410_DCON_WORD (2 << 20)
-
-#define S3C2410_DCON_AUTORELOAD (0 << 22)
-#define S3C2410_DCON_NORELOAD (1 << 22)
-#define S3C2410_DCON_HWTRIG (1 << 23)
-
-#ifdef CONFIG_CPU_S3C2440
-
-#define S3C2440_DIDSTC_CHKINT (1 << 2)
-
-#define S3C2440_DCON_CH0_I2SSDO (5 << 24)
-#define S3C2440_DCON_CH0_PCMIN (6 << 24)
-
-#define S3C2440_DCON_CH1_PCMOUT (5 << 24)
-#define S3C2440_DCON_CH1_SDI (6 << 24)
-
-#define S3C2440_DCON_CH2_PCMIN (5 << 24)
-#define S3C2440_DCON_CH2_MICIN (6 << 24)
-
-#define S3C2440_DCON_CH3_MICIN (5 << 24)
-#define S3C2440_DCON_CH3_PCMOUT (6 << 24)
-#endif /* CONFIG_CPU_S3C2440 */
-
-#ifdef CONFIG_CPU_S3C2412
-
-#define S3C2412_DMAREQSEL_SRC(x) ((x) << 1)
-
-#define S3C2412_DMAREQSEL_HW (1)
-
-#define S3C2412_DMAREQSEL_SPI0TX S3C2412_DMAREQSEL_SRC(0)
-#define S3C2412_DMAREQSEL_SPI0RX S3C2412_DMAREQSEL_SRC(1)
-#define S3C2412_DMAREQSEL_SPI1TX S3C2412_DMAREQSEL_SRC(2)
-#define S3C2412_DMAREQSEL_SPI1RX S3C2412_DMAREQSEL_SRC(3)
-#define S3C2412_DMAREQSEL_I2STX S3C2412_DMAREQSEL_SRC(4)
-#define S3C2412_DMAREQSEL_I2SRX S3C2412_DMAREQSEL_SRC(5)
-#define S3C2412_DMAREQSEL_TIMER S3C2412_DMAREQSEL_SRC(9)
-#define S3C2412_DMAREQSEL_SDI S3C2412_DMAREQSEL_SRC(10)
-#define S3C2412_DMAREQSEL_USBEP1 S3C2412_DMAREQSEL_SRC(13)
-#define S3C2412_DMAREQSEL_USBEP2 S3C2412_DMAREQSEL_SRC(14)
-#define S3C2412_DMAREQSEL_USBEP3 S3C2412_DMAREQSEL_SRC(15)
-#define S3C2412_DMAREQSEL_USBEP4 S3C2412_DMAREQSEL_SRC(16)
-#define S3C2412_DMAREQSEL_XDREQ0 S3C2412_DMAREQSEL_SRC(17)
-#define S3C2412_DMAREQSEL_XDREQ1 S3C2412_DMAREQSEL_SRC(18)
-#define S3C2412_DMAREQSEL_UART0_0 S3C2412_DMAREQSEL_SRC(19)
-#define S3C2412_DMAREQSEL_UART0_1 S3C2412_DMAREQSEL_SRC(20)
-#define S3C2412_DMAREQSEL_UART1_0 S3C2412_DMAREQSEL_SRC(21)
-#define S3C2412_DMAREQSEL_UART1_1 S3C2412_DMAREQSEL_SRC(22)
-#define S3C2412_DMAREQSEL_UART2_0 S3C2412_DMAREQSEL_SRC(23)
-#define S3C2412_DMAREQSEL_UART2_1 S3C2412_DMAREQSEL_SRC(24)
-#endif /* CONFIG_CPU_S3C2412 */
-
-#if defined(CONFIG_CPU_S3C2416) || defined(CONFIG_CPU_S3C2443)
-
-#define S3C2443_DMAREQSEL_SRC(x) ((x) << 1)
-
-#define S3C2443_DMAREQSEL_HW (1)
-
-#define S3C2443_DMAREQSEL_SPI0TX S3C2443_DMAREQSEL_SRC(0)
-#define S3C2443_DMAREQSEL_SPI0RX S3C2443_DMAREQSEL_SRC(1)
-#define S3C2443_DMAREQSEL_SPI1TX S3C2443_DMAREQSEL_SRC(2)
-#define S3C2443_DMAREQSEL_SPI1RX S3C2443_DMAREQSEL_SRC(3)
-#define S3C2443_DMAREQSEL_I2STX S3C2443_DMAREQSEL_SRC(4)
-#define S3C2443_DMAREQSEL_I2SRX S3C2443_DMAREQSEL_SRC(5)
-#define S3C2443_DMAREQSEL_TIMER S3C2443_DMAREQSEL_SRC(9)
-#define S3C2443_DMAREQSEL_SDI S3C2443_DMAREQSEL_SRC(10)
-#define S3C2443_DMAREQSEL_XDREQ0 S3C2443_DMAREQSEL_SRC(17)
-#define S3C2443_DMAREQSEL_XDREQ1 S3C2443_DMAREQSEL_SRC(18)
-#define S3C2443_DMAREQSEL_UART0_0 S3C2443_DMAREQSEL_SRC(19)
-#define S3C2443_DMAREQSEL_UART0_1 S3C2443_DMAREQSEL_SRC(20)
-#define S3C2443_DMAREQSEL_UART1_0 S3C2443_DMAREQSEL_SRC(21)
-#define S3C2443_DMAREQSEL_UART1_1 S3C2443_DMAREQSEL_SRC(22)
-#define S3C2443_DMAREQSEL_UART2_0 S3C2443_DMAREQSEL_SRC(23)
-#define S3C2443_DMAREQSEL_UART2_1 S3C2443_DMAREQSEL_SRC(24)
-#define S3C2443_DMAREQSEL_UART3_0 S3C2443_DMAREQSEL_SRC(25)
-#define S3C2443_DMAREQSEL_UART3_1 S3C2443_DMAREQSEL_SRC(26)
-#define S3C2443_DMAREQSEL_PCMOUT S3C2443_DMAREQSEL_SRC(27)
-#define S3C2443_DMAREQSEL_PCMIN S3C2443_DMAREQSEL_SRC(28)
-#define S3C2443_DMAREQSEL_MICIN S3C2443_DMAREQSEL_SRC(29)
-#endif /* CONFIG_CPU_S3C2443 */
-
-#endif /* __ASM_PLAT_REGS_DMA_H */
diff --git a/arch/arm/plat-samsung/s3c-dma-ops.c b/arch/arm/plat-samsung/s3c-dma-ops.c
deleted file mode 100644
index 98b10ba67dc7..000000000000
--- a/arch/arm/plat-samsung/s3c-dma-ops.c
+++ /dev/null
@@ -1,146 +0,0 @@
-/* linux/arch/arm/plat-samsung/s3c-dma-ops.c
- *
- * Copyright (c) 2011 Samsung Electronics Co., Ltd.
- * http://www.samsung.com
- *
- * Samsung S3C-DMA Operations
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- */
-
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/slab.h>
-#include <linux/types.h>
-#include <linux/export.h>
-
-#include <mach/dma.h>
-
-struct cb_data {
- void (*fp) (void *);
- void *fp_param;
- unsigned ch;
- struct list_head node;
-};
-
-static LIST_HEAD(dma_list);
-
-static void s3c_dma_cb(struct s3c2410_dma_chan *channel, void *param,
- int size, enum s3c2410_dma_buffresult res)
-{
- struct cb_data *data = param;
-
- data->fp(data->fp_param);
-}
-
-static unsigned s3c_dma_request(enum dma_ch dma_ch,
- struct samsung_dma_req *param,
- struct device *dev, char *ch_name)
-{
- struct cb_data *data;
-
- if (s3c2410_dma_request(dma_ch, param->client, NULL) < 0) {
- s3c2410_dma_free(dma_ch, param->client);
- return 0;
- }
-
- if (param->cap == DMA_CYCLIC)
- s3c2410_dma_setflags(dma_ch, S3C2410_DMAF_CIRCULAR);
-
- data = kzalloc(sizeof(struct cb_data), GFP_KERNEL);
- data->ch = dma_ch;
- list_add_tail(&data->node, &dma_list);
-
- return (unsigned)dma_ch;
-}
-
-static int s3c_dma_release(unsigned ch, void *param)
-{
- struct cb_data *data;
-
- list_for_each_entry(data, &dma_list, node)
- if (data->ch == ch)
- break;
- list_del(&data->node);
-
- s3c2410_dma_free(ch, param);
- kfree(data);
-
- return 0;
-}
-
-static int s3c_dma_config(unsigned ch, struct samsung_dma_config *param)
-{
- s3c2410_dma_devconfig(ch, param->direction, param->fifo);
- s3c2410_dma_config(ch, param->width);
-
- return 0;
-}
-
-static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep *param)
-{
- struct cb_data *data;
- dma_addr_t pos = param->buf;
- dma_addr_t end = param->buf + param->len;
-
- list_for_each_entry(data, &dma_list, node)
- if (data->ch == ch)
- break;
-
- if (!data->fp) {
- s3c2410_dma_set_buffdone_fn(ch, s3c_dma_cb);
- data->fp = param->fp;
- data->fp_param = param->fp_param;
- }
-
- if (param->cap != DMA_CYCLIC) {
- s3c2410_dma_enqueue(ch, (void *)data, param->buf, param->len);
- return 0;
- }
-
- while (pos < end) {
- s3c2410_dma_enqueue(ch, (void *)data, pos, param->period);
- pos += param->period;
- }
-
- return 0;
-}
-
-static inline int s3c_dma_trigger(unsigned ch)
-{
- return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_START);
-}
-
-static inline int s3c_dma_started(unsigned ch)
-{
- return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_STARTED);
-}
-
-static inline int s3c_dma_flush(unsigned ch)
-{
- return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_FLUSH);
-}
-
-static inline int s3c_dma_stop(unsigned ch)
-{
- return s3c2410_dma_ctrl(ch, S3C2410_DMAOP_STOP);
-}
-
-static struct samsung_dma_ops s3c_dma_ops = {
- .request = s3c_dma_request,
- .release = s3c_dma_release,
- .config = s3c_dma_config,
- .prepare = s3c_dma_prepare,
- .trigger = s3c_dma_trigger,
- .started = s3c_dma_started,
- .flush = s3c_dma_flush,
- .stop = s3c_dma_stop,
-};
-
-void *s3c_dma_get_ops(void)
-{
- return &s3c_dma_ops;
-}
-EXPORT_SYMBOL(s3c_dma_get_ops);
diff --git a/arch/arm/probes/Makefile b/arch/arm/probes/Makefile
new file mode 100644
index 000000000000..aa1f8590dcdd
--- /dev/null
+++ b/arch/arm/probes/Makefile
@@ -0,0 +1,7 @@
+obj-$(CONFIG_UPROBES) += decode.o decode-arm.o uprobes/
+obj-$(CONFIG_KPROBES) += decode.o kprobes/
+ifdef CONFIG_THUMB2_KERNEL
+obj-$(CONFIG_KPROBES) += decode-thumb.o
+else
+obj-$(CONFIG_KPROBES) += decode-arm.o
+endif
diff --git a/arch/arm/kernel/probes-arm.c b/arch/arm/probes/decode-arm.c
index 8eaef81d8344..f72c33a2dcfb 100644
--- a/arch/arm/kernel/probes-arm.c
+++ b/arch/arm/probes/decode-arm.c
@@ -1,5 +1,6 @@
/*
- * arch/arm/kernel/probes-arm.c
+ *
+ * arch/arm/probes/decode-arm.c
*
* Some code moved here from arch/arm/kernel/kprobes-arm.c
*
@@ -20,8 +21,8 @@
#include <linux/stddef.h>
#include <linux/ptrace.h>
-#include "probes.h"
-#include "probes-arm.h"
+#include "decode.h"
+#include "decode-arm.h"
#define sign_extend(x, signbit) ((x) | (0 - ((x) & (1 << (signbit)))))
@@ -369,17 +370,17 @@ static const union decode_item arm_cccc_001x_table[] = {
/* MOVW cccc 0011 0000 xxxx xxxx xxxx xxxx xxxx */
/* MOVT cccc 0011 0100 xxxx xxxx xxxx xxxx xxxx */
- DECODE_EMULATEX (0x0fb00000, 0x03000000, PROBES_DATA_PROCESSING_IMM,
+ DECODE_EMULATEX (0x0fb00000, 0x03000000, PROBES_MOV_HALFWORD,
REGS(0, NOPC, 0, 0, 0)),
/* YIELD cccc 0011 0010 0000 xxxx xxxx 0000 0001 */
DECODE_OR (0x0fff00ff, 0x03200001),
/* SEV cccc 0011 0010 0000 xxxx xxxx 0000 0100 */
- DECODE_EMULATE (0x0fff00ff, 0x03200004, PROBES_EMULATE_NONE),
+ DECODE_EMULATE (0x0fff00ff, 0x03200004, PROBES_SEV),
/* NOP cccc 0011 0010 0000 xxxx xxxx 0000 0000 */
/* WFE cccc 0011 0010 0000 xxxx xxxx 0000 0010 */
/* WFI cccc 0011 0010 0000 xxxx xxxx 0000 0011 */
- DECODE_SIMULATE (0x0fff00fc, 0x03200000, PROBES_SIMULATE_NOP),
+ DECODE_SIMULATE (0x0fff00fc, 0x03200000, PROBES_WFE),
/* DBG cccc 0011 0010 0000 xxxx xxxx ffff xxxx */
/* unallocated hints cccc 0011 0010 0000 xxxx xxxx xxxx xxxx */
/* MSR (immediate) cccc 0011 0x10 xxxx xxxx xxxx xxxx xxxx */
@@ -725,10 +726,11 @@ static void __kprobes arm_singlestep(probes_opcode_t insn,
*/
enum probes_insn __kprobes
arm_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
- bool emulate, const union decode_action *actions)
+ bool emulate, const union decode_action *actions,
+ const struct decode_checker *checkers[])
{
asi->insn_singlestep = arm_singlestep;
asi->insn_check_cc = probes_condition_checks[insn>>28];
return probes_decode_insn(insn, asi, probes_decode_arm_table, false,
- emulate, actions);
+ emulate, actions, checkers);
}
diff --git a/arch/arm/kernel/probes-arm.h b/arch/arm/probes/decode-arm.h
index ace6572f6e26..b3b80f6d414b 100644
--- a/arch/arm/kernel/probes-arm.h
+++ b/arch/arm/probes/decode-arm.h
@@ -1,5 +1,5 @@
/*
- * arch/arm/kernel/probes-arm.h
+ * arch/arm/probes/decode-arm.h
*
* Copyright 2013 Linaro Ltd.
* Written by: David A. Long
@@ -15,9 +15,9 @@
#ifndef _ARM_KERNEL_PROBES_ARM_H
#define _ARM_KERNEL_PROBES_ARM_H
+#include "decode.h"
+
enum probes_arm_action {
- PROBES_EMULATE_NONE,
- PROBES_SIMULATE_NOP,
PROBES_PRELOAD_IMM,
PROBES_PRELOAD_REG,
PROBES_BRANCH_IMM,
@@ -68,6 +68,7 @@ extern const union decode_item probes_decode_arm_table[];
enum probes_insn arm_probes_decode_insn(probes_opcode_t,
struct arch_probes_insn *, bool emulate,
- const union decode_action *actions);
+ const union decode_action *actions,
+ const struct decode_checker *checkers[]);
#endif
diff --git a/arch/arm/kernel/probes-thumb.c b/arch/arm/probes/decode-thumb.c
index 4131351e812f..985e7dd4cac6 100644
--- a/arch/arm/kernel/probes-thumb.c
+++ b/arch/arm/probes/decode-thumb.c
@@ -1,5 +1,5 @@
/*
- * arch/arm/kernel/probes-thumb.c
+ * arch/arm/probes/decode-thumb.c
*
* Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
*
@@ -12,8 +12,8 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include "probes.h"
-#include "probes-thumb.h"
+#include "decode.h"
+#include "decode-thumb.h"
static const union decode_item t32_table_1110_100x_x0xx[] = {
@@ -863,20 +863,22 @@ static void __kprobes thumb32_singlestep(probes_opcode_t opcode,
enum probes_insn __kprobes
thumb16_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
- bool emulate, const union decode_action *actions)
+ bool emulate, const union decode_action *actions,
+ const struct decode_checker *checkers[])
{
asi->insn_singlestep = thumb16_singlestep;
asi->insn_check_cc = thumb_check_cc;
return probes_decode_insn(insn, asi, probes_decode_thumb16_table, true,
- emulate, actions);
+ emulate, actions, checkers);
}
enum probes_insn __kprobes
thumb32_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
- bool emulate, const union decode_action *actions)
+ bool emulate, const union decode_action *actions,
+ const struct decode_checker *checkers[])
{
asi->insn_singlestep = thumb32_singlestep;
asi->insn_check_cc = thumb_check_cc;
return probes_decode_insn(insn, asi, probes_decode_thumb32_table, true,
- emulate, actions);
+ emulate, actions, checkers);
}
diff --git a/arch/arm/kernel/probes-thumb.h b/arch/arm/probes/decode-thumb.h
index 7c6f6ebe514f..8457add0a2d8 100644
--- a/arch/arm/kernel/probes-thumb.h
+++ b/arch/arm/probes/decode-thumb.h
@@ -1,5 +1,5 @@
/*
- * arch/arm/kernel/probes-thumb.h
+ * arch/arm/probes/decode-thumb.h
*
* Copyright 2013 Linaro Ltd.
* Written by: David A. Long
@@ -15,6 +15,8 @@
#ifndef _ARM_KERNEL_PROBES_THUMB_H
#define _ARM_KERNEL_PROBES_THUMB_H
+#include "decode.h"
+
/*
* True if current instruction is in an IT block.
*/
@@ -89,9 +91,11 @@ extern const union decode_item probes_decode_thumb16_table[];
enum probes_insn __kprobes
thumb16_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
- bool emulate, const union decode_action *actions);
+ bool emulate, const union decode_action *actions,
+ const struct decode_checker *checkers[]);
enum probes_insn __kprobes
thumb32_probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
- bool emulate, const union decode_action *actions);
+ bool emulate, const union decode_action *actions,
+ const struct decode_checker *checkers[]);
#endif
diff --git a/arch/arm/kernel/probes.c b/arch/arm/probes/decode.c
index a8ab540d7e73..880ebe0cdf19 100644
--- a/arch/arm/kernel/probes.c
+++ b/arch/arm/probes/decode.c
@@ -1,5 +1,5 @@
/*
- * arch/arm/kernel/probes.c
+ * arch/arm/probes/decode.c
*
* Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
*
@@ -17,7 +17,7 @@
#include <asm/ptrace.h>
#include <linux/bug.h>
-#include "probes.h"
+#include "decode.h"
#ifndef find_str_pc_offset
@@ -342,6 +342,31 @@ static const int decode_struct_sizes[NUM_DECODE_TYPES] = {
[DECODE_TYPE_REJECT] = sizeof(struct decode_reject)
};
+static int run_checkers(const struct decode_checker *checkers[],
+ int action, probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ const struct decode_checker **p;
+
+ if (!checkers)
+ return INSN_GOOD;
+
+ p = checkers;
+ while (*p != NULL) {
+ int retval;
+ probes_check_t *checker_func = (*p)[action].checker;
+
+ retval = INSN_GOOD;
+ if (checker_func)
+ retval = checker_func(insn, asi, h);
+ if (retval == INSN_REJECTED)
+ return retval;
+ p++;
+ }
+ return INSN_GOOD;
+}
+
/*
* probes_decode_insn operates on data tables in order to decode an ARM
* architecture instruction onto which a kprobe has been placed.
@@ -388,11 +413,34 @@ static const int decode_struct_sizes[NUM_DECODE_TYPES] = {
int __kprobes
probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
const union decode_item *table, bool thumb,
- bool emulate, const union decode_action *actions)
+ bool emulate, const union decode_action *actions,
+ const struct decode_checker *checkers[])
{
const struct decode_header *h = (struct decode_header *)table;
const struct decode_header *next;
bool matched = false;
+ /*
+ * @insn can be modified by decode_regs. Save its original
+ * value for checkers.
+ */
+ probes_opcode_t origin_insn = insn;
+
+ /*
+ * stack_space is initialized to 0 here. Checker functions
+ * should update is value if they find this is a stack store
+ * instruction: positive value means bytes of stack usage,
+ * negitive value means unable to determine stack usage
+ * statically. For instruction doesn't store to stack, checker
+ * do nothing with it.
+ */
+ asi->stack_space = 0;
+
+ /*
+ * Similarly to stack_space, register_usage_flags is filled by
+ * checkers. Its default value is set to ~0, which is 'all
+ * registers are used', to prevent any potential optimization.
+ */
+ asi->register_usage_flags = ~0UL;
if (emulate)
insn = prepare_emulated_insn(insn, asi, thumb);
@@ -422,24 +470,41 @@ probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
}
case DECODE_TYPE_CUSTOM: {
+ int err;
struct decode_custom *d = (struct decode_custom *)h;
- return actions[d->decoder.action].decoder(insn, asi, h);
+ int action = d->decoder.action;
+
+ err = run_checkers(checkers, action, origin_insn, asi, h);
+ if (err == INSN_REJECTED)
+ return INSN_REJECTED;
+ return actions[action].decoder(insn, asi, h);
}
case DECODE_TYPE_SIMULATE: {
+ int err;
struct decode_simulate *d = (struct decode_simulate *)h;
- asi->insn_handler = actions[d->handler.action].handler;
+ int action = d->handler.action;
+
+ err = run_checkers(checkers, action, origin_insn, asi, h);
+ if (err == INSN_REJECTED)
+ return INSN_REJECTED;
+ asi->insn_handler = actions[action].handler;
return INSN_GOOD_NO_SLOT;
}
case DECODE_TYPE_EMULATE: {
+ int err;
struct decode_emulate *d = (struct decode_emulate *)h;
+ int action = d->handler.action;
+
+ err = run_checkers(checkers, action, origin_insn, asi, h);
+ if (err == INSN_REJECTED)
+ return INSN_REJECTED;
if (!emulate)
- return actions[d->handler.action].decoder(insn,
- asi, h);
+ return actions[action].decoder(insn, asi, h);
- asi->insn_handler = actions[d->handler.action].handler;
+ asi->insn_handler = actions[action].handler;
set_emulated_insn(insn, asi, thumb);
return INSN_GOOD;
}
diff --git a/arch/arm/kernel/probes.h b/arch/arm/probes/decode.h
index dba9f2466a93..f9b08ba7fe73 100644
--- a/arch/arm/kernel/probes.h
+++ b/arch/arm/probes/decode.h
@@ -1,5 +1,5 @@
/*
- * arch/arm/kernel/probes.h
+ * arch/arm/probes/decode.h
*
* Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
*
@@ -314,6 +314,14 @@ union decode_action {
probes_custom_decode_t *decoder;
};
+typedef enum probes_insn (probes_check_t)(probes_opcode_t,
+ struct arch_probes_insn *,
+ const struct decode_header *);
+
+struct decode_checker {
+ probes_check_t *checker;
+};
+
#define DECODE_END \
{.bits = DECODE_TYPE_END}
@@ -402,6 +410,7 @@ probes_insn_handler_t probes_emulate_none;
int __kprobes
probes_decode_insn(probes_opcode_t insn, struct arch_probes_insn *asi,
const union decode_item *table, bool thumb, bool emulate,
- const union decode_action *actions);
+ const union decode_action *actions,
+ const struct decode_checker **checkers);
#endif
diff --git a/arch/arm/probes/kprobes/Makefile b/arch/arm/probes/kprobes/Makefile
new file mode 100644
index 000000000000..76a36bf102b7
--- /dev/null
+++ b/arch/arm/probes/kprobes/Makefile
@@ -0,0 +1,12 @@
+obj-$(CONFIG_KPROBES) += core.o actions-common.o checkers-common.o
+obj-$(CONFIG_ARM_KPROBES_TEST) += test-kprobes.o
+test-kprobes-objs := test-core.o
+
+ifdef CONFIG_THUMB2_KERNEL
+obj-$(CONFIG_KPROBES) += actions-thumb.o checkers-thumb.o
+test-kprobes-objs += test-thumb.o
+else
+obj-$(CONFIG_KPROBES) += actions-arm.o checkers-arm.o
+obj-$(CONFIG_OPTPROBES) += opt-arm.o
+test-kprobes-objs += test-arm.o
+endif
diff --git a/arch/arm/kernel/kprobes-arm.c b/arch/arm/probes/kprobes/actions-arm.c
index ac300c60d656..b9056d649607 100644
--- a/arch/arm/kernel/kprobes-arm.c
+++ b/arch/arm/probes/kprobes/actions-arm.c
@@ -1,5 +1,5 @@
/*
- * arch/arm/kernel/kprobes-decode.c
+ * arch/arm/probes/kprobes/actions-arm.c
*
* Copyright (C) 2006, 2007 Motorola Inc.
*
@@ -62,8 +62,9 @@
#include <linux/kprobes.h>
#include <linux/ptrace.h>
-#include "kprobes.h"
-#include "probes-arm.h"
+#include "../decode-arm.h"
+#include "core.h"
+#include "checkers.h"
#if __LINUX_ARM_ARCH__ >= 6
#define BLX(reg) "blx "reg" \n\t"
@@ -302,8 +303,6 @@ emulate_rdlo12rdhi16rn0rm8_rwflags_nopc(probes_opcode_t insn,
}
const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = {
- [PROBES_EMULATE_NONE] = {.handler = probes_emulate_none},
- [PROBES_SIMULATE_NOP] = {.handler = probes_simulate_nop},
[PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop},
[PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop},
[PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
@@ -341,3 +340,5 @@ const union decode_action kprobes_arm_actions[NUM_PROBES_ARM_ACTIONS] = {
[PROBES_BRANCH] = {.handler = simulate_bbl},
[PROBES_LDMSTM] = {.decoder = kprobe_decode_ldmstm}
};
+
+const struct decode_checker *kprobes_arm_checkers[] = {arm_stack_checker, arm_regs_checker, NULL};
diff --git a/arch/arm/kernel/kprobes-common.c b/arch/arm/probes/kprobes/actions-common.c
index 0bf5d64eba1d..bd20a71cd34a 100644
--- a/arch/arm/kernel/kprobes-common.c
+++ b/arch/arm/probes/kprobes/actions-common.c
@@ -1,5 +1,5 @@
/*
- * arch/arm/kernel/kprobes-common.c
+ * arch/arm/probes/kprobes/actions-common.c
*
* Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
*
@@ -15,7 +15,7 @@
#include <linux/kprobes.h>
#include <asm/opcodes.h>
-#include "kprobes.h"
+#include "core.h"
static void __kprobes simulate_ldm1stm1(probes_opcode_t insn,
diff --git a/arch/arm/kernel/kprobes-thumb.c b/arch/arm/probes/kprobes/actions-thumb.c
index 9495d7f3516f..07cfd9bef340 100644
--- a/arch/arm/kernel/kprobes-thumb.c
+++ b/arch/arm/probes/kprobes/actions-thumb.c
@@ -1,5 +1,5 @@
/*
- * arch/arm/kernel/kprobes-thumb.c
+ * arch/arm/probes/kprobes/actions-thumb.c
*
* Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
*
@@ -13,8 +13,9 @@
#include <linux/ptrace.h>
#include <linux/kprobes.h>
-#include "kprobes.h"
-#include "probes-thumb.h"
+#include "../decode-thumb.h"
+#include "core.h"
+#include "checkers.h"
/* These emulation encodings are functionally equivalent... */
#define t32_emulate_rd8rn16rm0ra12_noflags \
@@ -664,3 +665,6 @@ const union decode_action kprobes_t32_actions[NUM_PROBES_T32_ACTIONS] = {
[PROBES_T32_MUL_ADD_LONG] = {
.handler = t32_emulate_rdlo12rdhi8rn16rm0_noflags},
};
+
+const struct decode_checker *kprobes_t32_checkers[] = {t32_stack_checker, NULL};
+const struct decode_checker *kprobes_t16_checkers[] = {t16_stack_checker, NULL};
diff --git a/arch/arm/probes/kprobes/checkers-arm.c b/arch/arm/probes/kprobes/checkers-arm.c
new file mode 100644
index 000000000000..7b9817333b68
--- /dev/null
+++ b/arch/arm/probes/kprobes/checkers-arm.c
@@ -0,0 +1,192 @@
+/*
+ * arch/arm/probes/kprobes/checkers-arm.c
+ *
+ * Copyright (C) 2014 Huawei Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include "../decode.h"
+#include "../decode-arm.h"
+#include "checkers.h"
+
+static enum probes_insn __kprobes arm_check_stack(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ /*
+ * PROBES_LDRSTRD, PROBES_LDMSTM, PROBES_STORE,
+ * PROBES_STORE_EXTRA may get here. Simply mark all normal
+ * insns as STACK_USE_NONE.
+ */
+ static const union decode_item table[] = {
+ /*
+ * 'STR{,D,B,H}, Rt, [Rn, Rm]' should be marked as UNKNOWN
+ * if Rn or Rm is SP.
+ * x
+ * STR (register) cccc 011x x0x0 xxxx xxxx xxxx xxxx xxxx
+ * STRB (register) cccc 011x x1x0 xxxx xxxx xxxx xxxx xxxx
+ */
+ DECODE_OR (0x0e10000f, 0x0600000d),
+ DECODE_OR (0x0e1f0000, 0x060d0000),
+
+ /*
+ * x
+ * STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx
+ * STRH (register) cccc 000x x0x0 xxxx xxxx xxxx 1011 xxxx
+ */
+ DECODE_OR (0x0e5000bf, 0x000000bd),
+ DECODE_CUSTOM (0x0e5f00b0, 0x000d00b0, STACK_USE_UNKNOWN),
+
+ /*
+ * For PROBES_LDMSTM, only stmdx sp, [...] need to examine
+ *
+ * Bit B/A (bit 24) encodes arithmetic operation order. 1 means
+ * before, 0 means after.
+ * Bit I/D (bit 23) encodes arithmetic operation. 1 means
+ * increment, 0 means decrement.
+ *
+ * So:
+ * B I
+ * / /
+ * A D | Rn |
+ * STMDX SP, [...] cccc 100x 00x0 xxxx xxxx xxxx xxxx xxxx
+ */
+ DECODE_CUSTOM (0x0edf0000, 0x080d0000, STACK_USE_STMDX),
+
+ /* P U W | Rn | Rt | imm12 |*/
+ /* STR (immediate) cccc 010x x0x0 1101 xxxx xxxx xxxx xxxx */
+ /* STRB (immediate) cccc 010x x1x0 1101 xxxx xxxx xxxx xxxx */
+ /* P U W | Rn | Rt |imm4| |imm4|*/
+ /* STRD (immediate) cccc 000x x1x0 1101 xxxx xxxx 1111 xxxx */
+ /* STRH (immediate) cccc 000x x1x0 1101 xxxx xxxx 1011 xxxx */
+ /*
+ * index = (P == '1'); add = (U == '1').
+ * Above insns with:
+ * index == 0 (str{,d,h} rx, [sp], #+/-imm) or
+ * add == 1 (str{,d,h} rx, [sp, #+<imm>])
+ * should be STACK_USE_NONE.
+ * Only str{,b,d,h} rx,[sp,#-n] (P == 1 and U == 0) are
+ * required to be examined.
+ */
+ /* STR{,B} Rt,[SP,#-n] cccc 0101 0xx0 1101 xxxx xxxx xxxx xxxx */
+ DECODE_CUSTOM (0x0f9f0000, 0x050d0000, STACK_USE_FIXED_XXX),
+
+ /* STR{D,H} Rt,[SP,#-n] cccc 0001 01x0 1101 xxxx xxxx 1x11 xxxx */
+ DECODE_CUSTOM (0x0fdf00b0, 0x014d00b0, STACK_USE_FIXED_X0X),
+
+ /* fall through */
+ DECODE_CUSTOM (0, 0, STACK_USE_NONE),
+ DECODE_END
+ };
+
+ return probes_decode_insn(insn, asi, table, false, false, stack_check_actions, NULL);
+}
+
+const struct decode_checker arm_stack_checker[NUM_PROBES_ARM_ACTIONS] = {
+ [PROBES_LDRSTRD] = {.checker = arm_check_stack},
+ [PROBES_STORE_EXTRA] = {.checker = arm_check_stack},
+ [PROBES_STORE] = {.checker = arm_check_stack},
+ [PROBES_LDMSTM] = {.checker = arm_check_stack},
+};
+
+static enum probes_insn __kprobes arm_check_regs_nouse(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ asi->register_usage_flags = 0;
+ return INSN_GOOD;
+}
+
+static enum probes_insn arm_check_regs_normal(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ u32 regs = h->type_regs.bits >> DECODE_TYPE_BITS;
+ int i;
+
+ asi->register_usage_flags = 0;
+ for (i = 0; i < 5; regs >>= 4, insn >>= 4, i++)
+ if (regs & 0xf)
+ asi->register_usage_flags |= 1 << (insn & 0xf);
+
+ return INSN_GOOD;
+}
+
+
+static enum probes_insn arm_check_regs_ldmstm(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ unsigned int reglist = insn & 0xffff;
+ unsigned int rn = (insn >> 16) & 0xf;
+ asi->register_usage_flags = reglist | (1 << rn);
+ return INSN_GOOD;
+}
+
+static enum probes_insn arm_check_regs_mov_ip_sp(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ /* Instruction is 'mov ip, sp' i.e. 'mov r12, r13' */
+ asi->register_usage_flags = (1 << 12) | (1<< 13);
+ return INSN_GOOD;
+}
+
+/*
+ * | Rn |Rt/d| | Rm |
+ * LDRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1101 xxxx
+ * STRD (register) cccc 000x x0x0 xxxx xxxx xxxx 1111 xxxx
+ * | Rn |Rt/d| |imm4L|
+ * LDRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1101 xxxx
+ * STRD (immediate) cccc 000x x1x0 xxxx xxxx xxxx 1111 xxxx
+ *
+ * Such instructions access Rt/d and its next register, so different
+ * from others, a specific checker is required to handle this extra
+ * implicit register usage.
+ */
+static enum probes_insn arm_check_regs_ldrdstrd(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ int rdt = (insn >> 12) & 0xf;
+ arm_check_regs_normal(insn, asi, h);
+ asi->register_usage_flags |= 1 << (rdt + 1);
+ return INSN_GOOD;
+}
+
+
+const struct decode_checker arm_regs_checker[NUM_PROBES_ARM_ACTIONS] = {
+ [PROBES_MRS] = {.checker = arm_check_regs_normal},
+ [PROBES_SATURATING_ARITHMETIC] = {.checker = arm_check_regs_normal},
+ [PROBES_MUL1] = {.checker = arm_check_regs_normal},
+ [PROBES_MUL2] = {.checker = arm_check_regs_normal},
+ [PROBES_MUL_ADD_LONG] = {.checker = arm_check_regs_normal},
+ [PROBES_MUL_ADD] = {.checker = arm_check_regs_normal},
+ [PROBES_LOAD] = {.checker = arm_check_regs_normal},
+ [PROBES_LOAD_EXTRA] = {.checker = arm_check_regs_normal},
+ [PROBES_STORE] = {.checker = arm_check_regs_normal},
+ [PROBES_STORE_EXTRA] = {.checker = arm_check_regs_normal},
+ [PROBES_DATA_PROCESSING_REG] = {.checker = arm_check_regs_normal},
+ [PROBES_DATA_PROCESSING_IMM] = {.checker = arm_check_regs_normal},
+ [PROBES_SEV] = {.checker = arm_check_regs_nouse},
+ [PROBES_WFE] = {.checker = arm_check_regs_nouse},
+ [PROBES_SATURATE] = {.checker = arm_check_regs_normal},
+ [PROBES_REV] = {.checker = arm_check_regs_normal},
+ [PROBES_MMI] = {.checker = arm_check_regs_normal},
+ [PROBES_PACK] = {.checker = arm_check_regs_normal},
+ [PROBES_EXTEND] = {.checker = arm_check_regs_normal},
+ [PROBES_EXTEND_ADD] = {.checker = arm_check_regs_normal},
+ [PROBES_BITFIELD] = {.checker = arm_check_regs_normal},
+ [PROBES_LDMSTM] = {.checker = arm_check_regs_ldmstm},
+ [PROBES_MOV_IP_SP] = {.checker = arm_check_regs_mov_ip_sp},
+ [PROBES_LDRSTRD] = {.checker = arm_check_regs_ldrdstrd},
+};
diff --git a/arch/arm/probes/kprobes/checkers-common.c b/arch/arm/probes/kprobes/checkers-common.c
new file mode 100644
index 000000000000..971119c29474
--- /dev/null
+++ b/arch/arm/probes/kprobes/checkers-common.c
@@ -0,0 +1,101 @@
+/*
+ * arch/arm/probes/kprobes/checkers-common.c
+ *
+ * Copyright (C) 2014 Huawei Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include "../decode.h"
+#include "../decode-arm.h"
+#include "checkers.h"
+
+enum probes_insn checker_stack_use_none(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ asi->stack_space = 0;
+ return INSN_GOOD_NO_SLOT;
+}
+
+enum probes_insn checker_stack_use_unknown(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ asi->stack_space = -1;
+ return INSN_GOOD_NO_SLOT;
+}
+
+#ifdef CONFIG_THUMB2_KERNEL
+enum probes_insn checker_stack_use_imm_0xx(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ int imm = insn & 0xff;
+ asi->stack_space = imm;
+ return INSN_GOOD_NO_SLOT;
+}
+
+/*
+ * Different from other insn uses imm8, the real addressing offset of
+ * STRD in T32 encoding should be imm8 * 4. See ARMARM description.
+ */
+enum probes_insn checker_stack_use_t32strd(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ int imm = insn & 0xff;
+ asi->stack_space = imm << 2;
+ return INSN_GOOD_NO_SLOT;
+}
+#else
+enum probes_insn checker_stack_use_imm_x0x(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ int imm = ((insn & 0xf00) >> 4) + (insn & 0xf);
+ asi->stack_space = imm;
+ return INSN_GOOD_NO_SLOT;
+}
+#endif
+
+enum probes_insn checker_stack_use_imm_xxx(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ int imm = insn & 0xfff;
+ asi->stack_space = imm;
+ return INSN_GOOD_NO_SLOT;
+}
+
+enum probes_insn checker_stack_use_stmdx(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ unsigned int reglist = insn & 0xffff;
+ int pbit = insn & (1 << 24);
+ asi->stack_space = (hweight32(reglist) - (!pbit ? 1 : 0)) * 4;
+
+ return INSN_GOOD_NO_SLOT;
+}
+
+const union decode_action stack_check_actions[] = {
+ [STACK_USE_NONE] = {.decoder = checker_stack_use_none},
+ [STACK_USE_UNKNOWN] = {.decoder = checker_stack_use_unknown},
+#ifdef CONFIG_THUMB2_KERNEL
+ [STACK_USE_FIXED_0XX] = {.decoder = checker_stack_use_imm_0xx},
+ [STACK_USE_T32STRD] = {.decoder = checker_stack_use_t32strd},
+#else
+ [STACK_USE_FIXED_X0X] = {.decoder = checker_stack_use_imm_x0x},
+#endif
+ [STACK_USE_FIXED_XXX] = {.decoder = checker_stack_use_imm_xxx},
+ [STACK_USE_STMDX] = {.decoder = checker_stack_use_stmdx},
+};
diff --git a/arch/arm/probes/kprobes/checkers-thumb.c b/arch/arm/probes/kprobes/checkers-thumb.c
new file mode 100644
index 000000000000..d608e3b9017a
--- /dev/null
+++ b/arch/arm/probes/kprobes/checkers-thumb.c
@@ -0,0 +1,110 @@
+/*
+ * arch/arm/probes/kprobes/checkers-thumb.c
+ *
+ * Copyright (C) 2014 Huawei Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include "../decode.h"
+#include "../decode-thumb.h"
+#include "checkers.h"
+
+static enum probes_insn __kprobes t32_check_stack(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ /*
+ * PROBES_T32_LDMSTM, PROBES_T32_LDRDSTRD and PROBES_T32_LDRSTR
+ * may get here. Simply mark all normal insns as STACK_USE_NONE.
+ */
+ static const union decode_item table[] = {
+
+ /*
+ * First, filter out all ldr insns to make our life easier.
+ * Following load insns may come here:
+ * LDM, LDRD, LDR.
+ * In T32 encoding, bit 20 is enough for distinguishing
+ * load and store. All load insns have this bit set, when
+ * all store insns have this bit clear.
+ */
+ DECODE_CUSTOM (0x00100000, 0x00100000, STACK_USE_NONE),
+
+ /*
+ * Mark all 'STR{,B,H}, Rt, [Rn, Rm]' as STACK_USE_UNKNOWN
+ * if Rn or Rm is SP. T32 doesn't encode STRD.
+ */
+ /* xx | Rn | Rt | | Rm |*/
+ /* STR (register) 1111 1000 0100 xxxx xxxx 0000 00xx xxxx */
+ /* STRB (register) 1111 1000 0000 xxxx xxxx 0000 00xx xxxx */
+ /* STRH (register) 1111 1000 0010 xxxx xxxx 0000 00xx xxxx */
+ /* INVALID INSN 1111 1000 0110 xxxx xxxx 0000 00xx xxxx */
+ /* By Introducing INVALID INSN, bit 21 and 22 can be ignored. */
+ DECODE_OR (0xff9f0fc0, 0xf80d0000),
+ DECODE_CUSTOM (0xff900fcf, 0xf800000d, STACK_USE_UNKNOWN),
+
+
+ /* xx | Rn | Rt | PUW| imm8 |*/
+ /* STR (imm 8) 1111 1000 0100 1101 xxxx 110x xxxx xxxx */
+ /* STRB (imm 8) 1111 1000 0000 1101 xxxx 110x xxxx xxxx */
+ /* STRH (imm 8) 1111 1000 0010 1101 xxxx 110x xxxx xxxx */
+ /* INVALID INSN 1111 1000 0110 1101 xxxx 110x xxxx xxxx */
+ /* Only consider U == 0 and P == 1: strx rx, [sp, #-<imm>] */
+ DECODE_CUSTOM (0xff9f0e00, 0xf80d0c00, STACK_USE_FIXED_0XX),
+
+ /* For STR{,B,H} (imm 12), offset is always positive, so ignore them. */
+
+ /* P U W | Rn | Rt | Rt2| imm8 |*/
+ /* STRD (immediate) 1110 1001 01x0 1101 xxxx xxxx xxxx xxxx */
+ /*
+ * Only consider U == 0 and P == 1.
+ * Also note that STRD in T32 encoding is special:
+ * imm = ZeroExtend(imm8:'00', 32)
+ */
+ DECODE_CUSTOM (0xffdf0000, 0xe94d0000, STACK_USE_T32STRD),
+
+ /* | Rn | */
+ /* STMDB 1110 1001 00x0 1101 xxxx xxxx xxxx xxxx */
+ DECODE_CUSTOM (0xffdf0000, 0xe90d0000, STACK_USE_STMDX),
+
+ /* fall through */
+ DECODE_CUSTOM (0, 0, STACK_USE_NONE),
+ DECODE_END
+ };
+
+ return probes_decode_insn(insn, asi, table, false, false, stack_check_actions, NULL);
+}
+
+const struct decode_checker t32_stack_checker[NUM_PROBES_T32_ACTIONS] = {
+ [PROBES_T32_LDMSTM] = {.checker = t32_check_stack},
+ [PROBES_T32_LDRDSTRD] = {.checker = t32_check_stack},
+ [PROBES_T32_LDRSTR] = {.checker = t32_check_stack},
+};
+
+/*
+ * See following comments. This insn must be 'push'.
+ */
+static enum probes_insn __kprobes t16_check_stack(probes_opcode_t insn,
+ struct arch_probes_insn *asi,
+ const struct decode_header *h)
+{
+ unsigned int reglist = insn & 0x1ff;
+ asi->stack_space = hweight32(reglist) * 4;
+ return INSN_GOOD;
+}
+
+/*
+ * T16 encoding is simple: only the 'push' insn can need extra stack space.
+ * Other insns, like str, can only use r0-r7 as Rn.
+ */
+const struct decode_checker t16_stack_checker[NUM_PROBES_T16_ACTIONS] = {
+ [PROBES_T16_PUSH] = {.checker = t16_check_stack},
+};
diff --git a/arch/arm/probes/kprobes/checkers.h b/arch/arm/probes/kprobes/checkers.h
new file mode 100644
index 000000000000..cf6c9e74d666
--- /dev/null
+++ b/arch/arm/probes/kprobes/checkers.h
@@ -0,0 +1,55 @@
+/*
+ * arch/arm/probes/kprobes/checkers.h
+ *
+ * Copyright (C) 2014 Huawei Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ */
+#ifndef _ARM_KERNEL_PROBES_CHECKERS_H
+#define _ARM_KERNEL_PROBES_CHECKERS_H
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include "../decode.h"
+
+extern probes_check_t checker_stack_use_none;
+extern probes_check_t checker_stack_use_unknown;
+#ifdef CONFIG_THUMB2_KERNEL
+extern probes_check_t checker_stack_use_imm_0xx;
+#else
+extern probes_check_t checker_stack_use_imm_x0x;
+#endif
+extern probes_check_t checker_stack_use_imm_xxx;
+extern probes_check_t checker_stack_use_stmdx;
+
+enum {
+ STACK_USE_NONE,
+ STACK_USE_UNKNOWN,
+#ifdef CONFIG_THUMB2_KERNEL
+ STACK_USE_FIXED_0XX,
+ STACK_USE_T32STRD,
+#else
+ STACK_USE_FIXED_X0X,
+#endif
+ STACK_USE_FIXED_XXX,
+ STACK_USE_STMDX,
+ NUM_STACK_USE_TYPES
+};
+
+extern const union decode_action stack_check_actions[];
+
+#ifndef CONFIG_THUMB2_KERNEL
+extern const struct decode_checker arm_stack_checker[];
+extern const struct decode_checker arm_regs_checker[];
+#else
+#endif
+extern const struct decode_checker t32_stack_checker[];
+extern const struct decode_checker t16_stack_checker[];
+#endif
diff --git a/arch/arm/kernel/kprobes.c b/arch/arm/probes/kprobes/core.c
index 6d644202c8dc..a4ec240ee7ba 100644
--- a/arch/arm/kernel/kprobes.c
+++ b/arch/arm/probes/kprobes/core.c
@@ -30,11 +30,11 @@
#include <asm/cacheflush.h>
#include <linux/percpu.h>
#include <linux/bug.h>
+#include <asm/patch.h>
-#include "kprobes.h"
-#include "probes-arm.h"
-#include "probes-thumb.h"
-#include "patch.h"
+#include "../decode-arm.h"
+#include "../decode-thumb.h"
+#include "core.h"
#define MIN_STACK_SIZE(addr) \
min((unsigned long)MAX_STACK_SIZE, \
@@ -61,6 +61,7 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
kprobe_decode_insn_t *decode_insn;
const union decode_action *actions;
int is;
+ const struct decode_checker **checkers;
if (in_exception_text(addr))
return -EINVAL;
@@ -74,9 +75,11 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
insn = __opcode_thumb32_compose(insn, inst2);
decode_insn = thumb32_probes_decode_insn;
actions = kprobes_t32_actions;
+ checkers = kprobes_t32_checkers;
} else {
decode_insn = thumb16_probes_decode_insn;
actions = kprobes_t16_actions;
+ checkers = kprobes_t16_checkers;
}
#else /* !CONFIG_THUMB2_KERNEL */
thumb = false;
@@ -85,12 +88,13 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
insn = __mem_to_opcode_arm(*p->addr);
decode_insn = arm_probes_decode_insn;
actions = kprobes_arm_actions;
+ checkers = kprobes_arm_checkers;
#endif
p->opcode = insn;
p->ainsn.insn = tmp_insn;
- switch ((*decode_insn)(insn, &p->ainsn, true, actions)) {
+ switch ((*decode_insn)(insn, &p->ainsn, true, actions, checkers)) {
case INSN_REJECTED: /* not supported */
return -EINVAL;
@@ -111,6 +115,15 @@ int __kprobes arch_prepare_kprobe(struct kprobe *p)
break;
}
+ /*
+ * Never instrument insn like 'str r0, [sp, +/-r1]'. Also, insn likes
+ * 'str r0, [sp, #-68]' should also be prohibited.
+ * See __und_svc.
+ */
+ if ((p->ainsn.stack_space < 0) ||
+ (p->ainsn.stack_space > MAX_STACK_SIZE))
+ return -EINVAL;
+
return 0;
}
@@ -150,19 +163,31 @@ void __kprobes arch_arm_kprobe(struct kprobe *p)
* memory. It is also needed to atomically set the two half-words of a 32-bit
* Thumb breakpoint.
*/
-int __kprobes __arch_disarm_kprobe(void *p)
-{
- struct kprobe *kp = p;
- void *addr = (void *)((uintptr_t)kp->addr & ~1);
-
- __patch_text(addr, kp->opcode);
+struct patch {
+ void *addr;
+ unsigned int insn;
+};
+static int __kprobes_remove_breakpoint(void *data)
+{
+ struct patch *p = data;
+ __patch_text(p->addr, p->insn);
return 0;
}
+void __kprobes kprobes_remove_breakpoint(void *addr, unsigned int insn)
+{
+ struct patch p = {
+ .addr = addr,
+ .insn = insn,
+ };
+ stop_machine(__kprobes_remove_breakpoint, &p, cpu_online_mask);
+}
+
void __kprobes arch_disarm_kprobe(struct kprobe *p)
{
- stop_machine(__arch_disarm_kprobe, p, cpu_online_mask);
+ kprobes_remove_breakpoint((void *)((uintptr_t)p->addr & ~1),
+ p->opcode);
}
void __kprobes arch_remove_kprobe(struct kprobe *p)
diff --git a/arch/arm/kernel/kprobes.h b/arch/arm/probes/kprobes/core.h
index 9a2712ecefc3..ec5d1f20a085 100644
--- a/arch/arm/kernel/kprobes.h
+++ b/arch/arm/probes/kprobes/core.h
@@ -19,7 +19,8 @@
#ifndef _ARM_KERNEL_KPROBES_H
#define _ARM_KERNEL_KPROBES_H
-#include "probes.h"
+#include <asm/kprobes.h>
+#include "../decode.h"
/*
* These undefined instructions must be unique and
@@ -29,6 +30,8 @@
#define KPROBE_THUMB16_BREAKPOINT_INSTRUCTION 0xde18
#define KPROBE_THUMB32_BREAKPOINT_INSTRUCTION 0xf7f0a018
+extern void kprobes_remove_breakpoint(void *addr, unsigned int insn);
+
enum probes_insn __kprobes
kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_probes_insn *asi,
const struct decode_header *h);
@@ -36,16 +39,19 @@ kprobe_decode_ldmstm(kprobe_opcode_t insn, struct arch_probes_insn *asi,
typedef enum probes_insn (kprobe_decode_insn_t)(probes_opcode_t,
struct arch_probes_insn *,
bool,
- const union decode_action *);
+ const union decode_action *,
+ const struct decode_checker *[]);
#ifdef CONFIG_THUMB2_KERNEL
extern const union decode_action kprobes_t32_actions[];
extern const union decode_action kprobes_t16_actions[];
-
+extern const struct decode_checker *kprobes_t32_checkers[];
+extern const struct decode_checker *kprobes_t16_checkers[];
#else /* !CONFIG_THUMB2_KERNEL */
extern const union decode_action kprobes_arm_actions[];
+extern const struct decode_checker *kprobes_arm_checkers[];
#endif
diff --git a/arch/arm/probes/kprobes/opt-arm.c b/arch/arm/probes/kprobes/opt-arm.c
new file mode 100644
index 000000000000..bcdecc25461b
--- /dev/null
+++ b/arch/arm/probes/kprobes/opt-arm.c
@@ -0,0 +1,370 @@
+/*
+ * Kernel Probes Jump Optimization (Optprobes)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2002, 2004
+ * Copyright (C) Hitachi Ltd., 2012
+ * Copyright (C) Huawei Inc., 2014
+ */
+
+#include <linux/kprobes.h>
+#include <linux/jump_label.h>
+#include <asm/kprobes.h>
+#include <asm/cacheflush.h>
+/* for arm_gen_branch */
+#include <asm/insn.h>
+/* for patch_text */
+#include <asm/patch.h>
+
+#include "core.h"
+
+/*
+ * See register_usage_flags. If the probed instruction doesn't use PC,
+ * we can copy it into template and have it executed directly without
+ * simulation or emulation.
+ */
+#define ARM_REG_PC 15
+#define can_kprobe_direct_exec(m) (!test_bit(ARM_REG_PC, &(m)))
+
+/*
+ * NOTE: the first sub and add instruction will be modified according
+ * to the stack cost of the instruction.
+ */
+asm (
+ ".global optprobe_template_entry\n"
+ "optprobe_template_entry:\n"
+ ".global optprobe_template_sub_sp\n"
+ "optprobe_template_sub_sp:"
+ " sub sp, sp, #0xff\n"
+ " stmia sp, {r0 - r14} \n"
+ ".global optprobe_template_add_sp\n"
+ "optprobe_template_add_sp:"
+ " add r3, sp, #0xff\n"
+ " str r3, [sp, #52]\n"
+ " mrs r4, cpsr\n"
+ " str r4, [sp, #64]\n"
+ " mov r1, sp\n"
+ " ldr r0, 1f\n"
+ " ldr r2, 2f\n"
+ /*
+ * AEABI requires an 8-bytes alignment stack. If
+ * SP % 8 != 0 (SP % 4 == 0 should be ensured),
+ * alloc more bytes here.
+ */
+ " and r4, sp, #4\n"
+ " sub sp, sp, r4\n"
+#if __LINUX_ARM_ARCH__ >= 5
+ " blx r2\n"
+#else
+ " mov lr, pc\n"
+ " mov pc, r2\n"
+#endif
+ " add sp, sp, r4\n"
+ " ldr r1, [sp, #64]\n"
+ " tst r1, #"__stringify(PSR_T_BIT)"\n"
+ " ldrne r2, [sp, #60]\n"
+ " orrne r2, #1\n"
+ " strne r2, [sp, #60] @ set bit0 of PC for thumb\n"
+ " msr cpsr_cxsf, r1\n"
+ ".global optprobe_template_restore_begin\n"
+ "optprobe_template_restore_begin:\n"
+ " ldmia sp, {r0 - r15}\n"
+ ".global optprobe_template_restore_orig_insn\n"
+ "optprobe_template_restore_orig_insn:\n"
+ " nop\n"
+ ".global optprobe_template_restore_end\n"
+ "optprobe_template_restore_end:\n"
+ " nop\n"
+ ".global optprobe_template_val\n"
+ "optprobe_template_val:\n"
+ "1: .long 0\n"
+ ".global optprobe_template_call\n"
+ "optprobe_template_call:\n"
+ "2: .long 0\n"
+ ".global optprobe_template_end\n"
+ "optprobe_template_end:\n");
+
+#define TMPL_VAL_IDX \
+ ((unsigned long *)&optprobe_template_val - (unsigned long *)&optprobe_template_entry)
+#define TMPL_CALL_IDX \
+ ((unsigned long *)&optprobe_template_call - (unsigned long *)&optprobe_template_entry)
+#define TMPL_END_IDX \
+ ((unsigned long *)&optprobe_template_end - (unsigned long *)&optprobe_template_entry)
+#define TMPL_ADD_SP \
+ ((unsigned long *)&optprobe_template_add_sp - (unsigned long *)&optprobe_template_entry)
+#define TMPL_SUB_SP \
+ ((unsigned long *)&optprobe_template_sub_sp - (unsigned long *)&optprobe_template_entry)
+#define TMPL_RESTORE_BEGIN \
+ ((unsigned long *)&optprobe_template_restore_begin - (unsigned long *)&optprobe_template_entry)
+#define TMPL_RESTORE_ORIGN_INSN \
+ ((unsigned long *)&optprobe_template_restore_orig_insn - (unsigned long *)&optprobe_template_entry)
+#define TMPL_RESTORE_END \
+ ((unsigned long *)&optprobe_template_restore_end - (unsigned long *)&optprobe_template_entry)
+
+/*
+ * ARM can always optimize an instruction when using ARM ISA, except
+ * instructions like 'str r0, [sp, r1]' which store to stack and unable
+ * to determine stack space consumption statically.
+ */
+int arch_prepared_optinsn(struct arch_optimized_insn *optinsn)
+{
+ return optinsn->insn != NULL;
+}
+
+/*
+ * In ARM ISA, kprobe opt always replace one instruction (4 bytes
+ * aligned and 4 bytes long). It is impossible to encounter another
+ * kprobe in the address range. So always return 0.
+ */
+int arch_check_optimized_kprobe(struct optimized_kprobe *op)
+{
+ return 0;
+}
+
+/* Caller must ensure addr & 3 == 0 */
+static int can_optimize(struct kprobe *kp)
+{
+ if (kp->ainsn.stack_space < 0)
+ return 0;
+ /*
+ * 255 is the biggest imm can be used in 'sub r0, r0, #<imm>'.
+ * Number larger than 255 needs special encoding.
+ */
+ if (kp->ainsn.stack_space > 255 - sizeof(struct pt_regs))
+ return 0;
+ return 1;
+}
+
+/* Free optimized instruction slot */
+static void
+__arch_remove_optimized_kprobe(struct optimized_kprobe *op, int dirty)
+{
+ if (op->optinsn.insn) {
+ free_optinsn_slot(op->optinsn.insn, dirty);
+ op->optinsn.insn = NULL;
+ }
+}
+
+extern void kprobe_handler(struct pt_regs *regs);
+
+static void
+optimized_callback(struct optimized_kprobe *op, struct pt_regs *regs)
+{
+ unsigned long flags;
+ struct kprobe *p = &op->kp;
+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
+
+ /* Save skipped registers */
+ regs->ARM_pc = (unsigned long)op->kp.addr;
+ regs->ARM_ORIG_r0 = ~0UL;
+
+ local_irq_save(flags);
+
+ if (kprobe_running()) {
+ kprobes_inc_nmissed_count(&op->kp);
+ } else {
+ __this_cpu_write(current_kprobe, &op->kp);
+ kcb->kprobe_status = KPROBE_HIT_ACTIVE;
+ opt_pre_handler(&op->kp, regs);
+ __this_cpu_write(current_kprobe, NULL);
+ }
+
+ /*
+ * We singlestep the replaced instruction only when it can't be
+ * executed directly during restore.
+ */
+ if (!p->ainsn.kprobe_direct_exec)
+ op->kp.ainsn.insn_singlestep(p->opcode, &p->ainsn, regs);
+
+ local_irq_restore(flags);
+}
+
+int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *orig)
+{
+ kprobe_opcode_t *code;
+ unsigned long rel_chk;
+ unsigned long val;
+ unsigned long stack_protect = sizeof(struct pt_regs);
+
+ if (!can_optimize(orig))
+ return -EILSEQ;
+
+ code = get_optinsn_slot();
+ if (!code)
+ return -ENOMEM;
+
+ /*
+ * Verify if the address gap is in 32MiB range, because this uses
+ * a relative jump.
+ *
+ * kprobe opt use a 'b' instruction to branch to optinsn.insn.
+ * According to ARM manual, branch instruction is:
+ *
+ * 31 28 27 24 23 0
+ * +------+---+---+---+---+----------------+
+ * | cond | 1 | 0 | 1 | 0 | imm24 |
+ * +------+---+---+---+---+----------------+
+ *
+ * imm24 is a signed 24 bits integer. The real branch offset is computed
+ * by: imm32 = SignExtend(imm24:'00', 32);
+ *
+ * So the maximum forward branch should be:
+ * (0x007fffff << 2) = 0x01fffffc = 0x1fffffc
+ * The maximum backword branch should be:
+ * (0xff800000 << 2) = 0xfe000000 = -0x2000000
+ *
+ * We can simply check (rel & 0xfe000003):
+ * if rel is positive, (rel & 0xfe000000) shoule be 0
+ * if rel is negitive, (rel & 0xfe000000) should be 0xfe000000
+ * the last '3' is used for alignment checking.
+ */
+ rel_chk = (unsigned long)((long)code -
+ (long)orig->addr + 8) & 0xfe000003;
+
+ if ((rel_chk != 0) && (rel_chk != 0xfe000000)) {
+ /*
+ * Different from x86, we free code buf directly instead of
+ * calling __arch_remove_optimized_kprobe() because
+ * we have not fill any field in op.
+ */
+ free_optinsn_slot(code, 0);
+ return -ERANGE;
+ }
+
+ /* Copy arch-dep-instance from template. */
+ memcpy(code, &optprobe_template_entry,
+ TMPL_END_IDX * sizeof(kprobe_opcode_t));
+
+ /* Adjust buffer according to instruction. */
+ BUG_ON(orig->ainsn.stack_space < 0);
+
+ stack_protect += orig->ainsn.stack_space;
+
+ /* Should have been filtered by can_optimize(). */
+ BUG_ON(stack_protect > 255);
+
+ /* Create a 'sub sp, sp, #<stack_protect>' */
+ code[TMPL_SUB_SP] = __opcode_to_mem_arm(0xe24dd000 | stack_protect);
+ /* Create a 'add r3, sp, #<stack_protect>' */
+ code[TMPL_ADD_SP] = __opcode_to_mem_arm(0xe28d3000 | stack_protect);
+
+ /* Set probe information */
+ val = (unsigned long)op;
+ code[TMPL_VAL_IDX] = val;
+
+ /* Set probe function call */
+ val = (unsigned long)optimized_callback;
+ code[TMPL_CALL_IDX] = val;
+
+ /* If possible, copy insn and have it executed during restore */
+ orig->ainsn.kprobe_direct_exec = false;
+ if (can_kprobe_direct_exec(orig->ainsn.register_usage_flags)) {
+ kprobe_opcode_t final_branch = arm_gen_branch(
+ (unsigned long)(&code[TMPL_RESTORE_END]),
+ (unsigned long)(op->kp.addr) + 4);
+ if (final_branch != 0) {
+ /*
+ * Replace original 'ldmia sp, {r0 - r15}' with
+ * 'ldmia {r0 - r14}', restore all registers except pc.
+ */
+ code[TMPL_RESTORE_BEGIN] = __opcode_to_mem_arm(0xe89d7fff);
+
+ /* The original probed instruction */
+ code[TMPL_RESTORE_ORIGN_INSN] = __opcode_to_mem_arm(orig->opcode);
+
+ /* Jump back to next instruction */
+ code[TMPL_RESTORE_END] = __opcode_to_mem_arm(final_branch);
+ orig->ainsn.kprobe_direct_exec = true;
+ }
+ }
+
+ flush_icache_range((unsigned long)code,
+ (unsigned long)(&code[TMPL_END_IDX]));
+
+ /* Set op->optinsn.insn means prepared. */
+ op->optinsn.insn = code;
+ return 0;
+}
+
+void __kprobes arch_optimize_kprobes(struct list_head *oplist)
+{
+ struct optimized_kprobe *op, *tmp;
+
+ list_for_each_entry_safe(op, tmp, oplist, list) {
+ unsigned long insn;
+ WARN_ON(kprobe_disabled(&op->kp));
+
+ /*
+ * Backup instructions which will be replaced
+ * by jump address
+ */
+ memcpy(op->optinsn.copied_insn, op->kp.addr,
+ RELATIVEJUMP_SIZE);
+
+ insn = arm_gen_branch((unsigned long)op->kp.addr,
+ (unsigned long)op->optinsn.insn);
+ BUG_ON(insn == 0);
+
+ /*
+ * Make it a conditional branch if replaced insn
+ * is consitional
+ */
+ insn = (__mem_to_opcode_arm(
+ op->optinsn.copied_insn[0]) & 0xf0000000) |
+ (insn & 0x0fffffff);
+
+ /*
+ * Similar to __arch_disarm_kprobe, operations which
+ * removing breakpoints must be wrapped by stop_machine
+ * to avoid racing.
+ */
+ kprobes_remove_breakpoint(op->kp.addr, insn);
+
+ list_del_init(&op->list);
+ }
+}
+
+void arch_unoptimize_kprobe(struct optimized_kprobe *op)
+{
+ arch_arm_kprobe(&op->kp);
+}
+
+/*
+ * Recover original instructions and breakpoints from relative jumps.
+ * Caller must call with locking kprobe_mutex.
+ */
+void arch_unoptimize_kprobes(struct list_head *oplist,
+ struct list_head *done_list)
+{
+ struct optimized_kprobe *op, *tmp;
+
+ list_for_each_entry_safe(op, tmp, oplist, list) {
+ arch_unoptimize_kprobe(op);
+ list_move(&op->list, done_list);
+ }
+}
+
+int arch_within_optimized_kprobe(struct optimized_kprobe *op,
+ unsigned long addr)
+{
+ return ((unsigned long)op->kp.addr <= addr &&
+ (unsigned long)op->kp.addr + RELATIVEJUMP_SIZE > addr);
+}
+
+void arch_remove_optimized_kprobe(struct optimized_kprobe *op)
+{
+ __arch_remove_optimized_kprobe(op, 1);
+}
diff --git a/arch/arm/kernel/kprobes-test-arm.c b/arch/arm/probes/kprobes/test-arm.c
index cb1424240ff6..8866aedfdea2 100644
--- a/arch/arm/kernel/kprobes-test-arm.c
+++ b/arch/arm/probes/kprobes/test-arm.c
@@ -12,8 +12,9 @@
#include <linux/module.h>
#include <asm/system_info.h>
#include <asm/opcodes.h>
+#include <asm/probes.h>
-#include "kprobes-test.h"
+#include "test-core.h"
#define TEST_ISA "32"
@@ -203,9 +204,9 @@ void kprobe_arm_test_cases(void)
#endif
TEST_GROUP("Miscellaneous instructions")
- TEST("mrs r0, cpsr")
- TEST("mrspl r7, cpsr")
- TEST("mrs r14, cpsr")
+ TEST_RMASKED("mrs r",0,~PSR_IGNORE_BITS,", cpsr")
+ TEST_RMASKED("mrspl r",7,~PSR_IGNORE_BITS,", cpsr")
+ TEST_RMASKED("mrs r",14,~PSR_IGNORE_BITS,", cpsr")
TEST_UNSUPPORTED(__inst_arm(0xe10ff000) " @ mrs r15, cpsr")
TEST_UNSUPPORTED("mrs r0, spsr")
TEST_UNSUPPORTED("mrs lr, spsr")
@@ -214,9 +215,12 @@ void kprobe_arm_test_cases(void)
TEST_UNSUPPORTED("msr cpsr_f, lr")
TEST_UNSUPPORTED("msr spsr, r0")
+#if __LINUX_ARM_ARCH__ >= 5 || \
+ (__LINUX_ARM_ARCH__ == 4 && !defined(CONFIG_CPU_32v4))
TEST_BF_R("bx r",0,2f,"")
TEST_BB_R("bx r",7,2f,"")
TEST_BF_R("bxeq r",14,2f,"")
+#endif
#if __LINUX_ARM_ARCH__ >= 5
TEST_R("clz r0, r",0, 0x0,"")
@@ -476,7 +480,9 @@ void kprobe_arm_test_cases(void)
TEST_GROUP("Extra load/store instructions")
TEST_RPR( "strh r",0, VAL1,", [r",1, 48,", -r",2, 24,"]")
- TEST_RPR( "streqh r",14,VAL2,", [r",13,0, ", r",12, 48,"]")
+ TEST_RPR( "streqh r",14,VAL2,", [r",11,0, ", r",12, 48,"]")
+ TEST_UNSUPPORTED( "streqh r14, [r13, r12]")
+ TEST_UNSUPPORTED( "streqh r14, [r12, r13]")
TEST_RPR( "strh r",1, VAL1,", [r",2, 24,", r",3, 48,"]!")
TEST_RPR( "strneh r",12,VAL2,", [r",11,48,", -r",10,24,"]!")
TEST_RPR( "strh r",2, VAL1,", [r",3, 24,"], r",4, 48,"")
@@ -501,6 +507,9 @@ void kprobe_arm_test_cases(void)
TEST_RP( "strplh r",12,VAL2,", [r",11,24,", #-4]!")
TEST_RP( "strh r",2, VAL1,", [r",3, 24,"], #48")
TEST_RP( "strh r",10,VAL2,", [r",9, 64,"], #-48")
+ TEST_RP( "strh r",3, VAL1,", [r",13,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!")
+ TEST_UNSUPPORTED("strh r3, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!")
+ TEST_RP( "strh r",4, VAL1,", [r",14,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!")
TEST_UNSUPPORTED(__inst_arm(0xe1efc3b0) " @ strh r12, [pc, #48]!")
TEST_UNSUPPORTED(__inst_arm(0xe0c9f3b0) " @ strh pc, [r9], #48")
@@ -565,7 +574,9 @@ void kprobe_arm_test_cases(void)
#if __LINUX_ARM_ARCH__ >= 5
TEST_RPR( "strd r",0, VAL1,", [r",1, 48,", -r",2,24,"]")
- TEST_RPR( "strccd r",8, VAL2,", [r",13,0, ", r",12,48,"]")
+ TEST_RPR( "strccd r",8, VAL2,", [r",11,0, ", r",12,48,"]")
+ TEST_UNSUPPORTED( "strccd r8, [r13, r12]")
+ TEST_UNSUPPORTED( "strccd r8, [r12, r13]")
TEST_RPR( "strd r",4, VAL1,", [r",2, 24,", r",3, 48,"]!")
TEST_RPR( "strcsd r",12,VAL2,", [r",11,48,", -r",10,24,"]!")
TEST_RPR( "strd r",2, VAL1,", [r",5, 24,"], r",4,48,"")
@@ -589,6 +600,9 @@ void kprobe_arm_test_cases(void)
TEST_RP( "strvcd r",12,VAL2,", [r",11,24,", #-16]!")
TEST_RP( "strd r",2, VAL1,", [r",4, 24,"], #48")
TEST_RP( "strd r",10,VAL2,", [r",9, 64,"], #-48")
+ TEST_RP( "strd r",6, VAL1,", [r",13,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!")
+ TEST_UNSUPPORTED("strd r6, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!")
+ TEST_RP( "strd r",4, VAL1,", [r",12,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!")
TEST_UNSUPPORTED(__inst_arm(0xe1efc3f0) " @ strd r12, [pc, #48]!")
TEST_P( "ldrd r0, [r",0, 24,", #-8]")
@@ -637,14 +651,20 @@ void kprobe_arm_test_cases(void)
TEST_RP( "str"byte" r",12,VAL2,", [r",11,24,", #-4]!") \
TEST_RP( "str"byte" r",2, VAL1,", [r",3, 24,"], #48") \
TEST_RP( "str"byte" r",10,VAL2,", [r",9, 64,"], #-48") \
+ TEST_RP( "str"byte" r",3, VAL1,", [r",13,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!") \
+ TEST_UNSUPPORTED("str"byte" r3, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!") \
+ TEST_RP( "str"byte" r",4, VAL1,", [r",10,TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!") \
TEST_RPR("str"byte" r",0, VAL1,", [r",1, 48,", -r",2, 24,"]") \
- TEST_RPR("str"byte" r",14,VAL2,", [r",13,0, ", r",12, 48,"]") \
+ TEST_RPR("str"byte" r",14,VAL2,", [r",11,0, ", r",12, 48,"]") \
+ TEST_UNSUPPORTED("str"byte" r14, [r13, r12]") \
+ TEST_UNSUPPORTED("str"byte" r14, [r12, r13]") \
TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 48,"]!") \
TEST_RPR("str"byte" r",12,VAL2,", [r",11,48,", -r",10,24,"]!") \
TEST_RPR("str"byte" r",2, VAL1,", [r",3, 24,"], r",4, 48,"") \
TEST_RPR("str"byte" r",10,VAL2,", [r",9, 48,"], -r",11,24,"") \
TEST_RPR("str"byte" r",0, VAL1,", [r",1, 24,", r",2, 32,", asl #1]")\
- TEST_RPR("str"byte" r",14,VAL2,", [r",13,0, ", r",12, 32,", lsr #2]")\
+ TEST_RPR("str"byte" r",14,VAL2,", [r",11,0, ", r",12, 32,", lsr #2]")\
+ TEST_UNSUPPORTED("str"byte" r14, [r13, r12, lsr #2]") \
TEST_RPR("str"byte" r",1, VAL1,", [r",2, 24,", r",3, 32,", asr #3]!")\
TEST_RPR("str"byte" r",12,VAL2,", [r",11,24,", r",10, 4,", ror #31]!")\
TEST_P( "ldr"byte" r0, [r",0, 24,", #-2]") \
@@ -668,12 +688,12 @@ void kprobe_arm_test_cases(void)
LOAD_STORE("")
TEST_P( "str pc, [r",0,0,", #15*4]")
- TEST_R( "str pc, [sp, r",2,15*4,"]")
+ TEST_UNSUPPORTED( "str pc, [sp, r2]")
TEST_BF( "ldr pc, [sp, #15*4]")
TEST_BF_R("ldr pc, [sp, r",2,15*4,"]")
TEST_P( "str sp, [r",0,0,", #13*4]")
- TEST_R( "str sp, [sp, r",2,13*4,"]")
+ TEST_UNSUPPORTED( "str sp, [sp, r2]")
TEST_BF( "ldr sp, [sp, #13*4]")
TEST_BF_R("ldr sp, [sp, r",2,13*4,"]")
diff --git a/arch/arm/kernel/kprobes-test.c b/arch/arm/probes/kprobes/test-core.c
index b206d7790c77..9775de22e2ff 100644
--- a/arch/arm/kernel/kprobes-test.c
+++ b/arch/arm/probes/kprobes/test-core.c
@@ -209,10 +209,10 @@
#include <linux/bug.h>
#include <asm/opcodes.h>
-#include "kprobes.h"
-#include "probes-arm.h"
-#include "probes-thumb.h"
-#include "kprobes-test.h"
+#include "core.h"
+#include "test-core.h"
+#include "../decode-arm.h"
+#include "../decode-thumb.h"
#define BENCHMARKING 1
@@ -236,6 +236,8 @@ static int tests_failed;
#ifndef CONFIG_THUMB2_KERNEL
+#define RET(reg) "mov pc, "#reg
+
long arm_func(long r0, long r1);
static void __used __naked __arm_kprobes_test_func(void)
@@ -245,7 +247,7 @@ static void __used __naked __arm_kprobes_test_func(void)
".type arm_func, %%function \n\t"
"arm_func: \n\t"
"adds r0, r0, r1 \n\t"
- "bx lr \n\t"
+ "mov pc, lr \n\t"
".code "NORMAL_ISA /* Back to Thumb if necessary */
: : : "r0", "r1", "cc"
);
@@ -253,6 +255,8 @@ static void __used __naked __arm_kprobes_test_func(void)
#else /* CONFIG_THUMB2_KERNEL */
+#define RET(reg) "bx "#reg
+
long thumb16_func(long r0, long r1);
long thumb32even_func(long r0, long r1);
long thumb32odd_func(long r0, long r1);
@@ -494,7 +498,7 @@ static void __naked benchmark_nop(void)
{
__asm__ __volatile__ (
"nop \n\t"
- "bx lr"
+ RET(lr)" \n\t"
);
}
@@ -977,7 +981,7 @@ void __naked __kprobes_test_case_start(void)
"bic r0, lr, #1 @ r0 = inline data \n\t"
"mov r1, sp \n\t"
"bl kprobes_test_case_start \n\t"
- "bx r0 \n\t"
+ RET(r0)" \n\t"
);
}
@@ -1056,15 +1060,6 @@ static int test_case_run_count;
static bool test_case_is_thumb;
static int test_instance;
-/*
- * We ignore the state of the imprecise abort disable flag (CPSR.A) because this
- * can change randomly as the kernel doesn't take care to preserve or initialise
- * this across context switches. Also, with Security Extentions, the flag may
- * not be under control of the kernel; for this reason we ignore the state of
- * the FIQ disable flag CPSR.F as well.
- */
-#define PSR_IGNORE_BITS (PSR_A_BIT | PSR_F_BIT)
-
static unsigned long test_check_cc(int cc, unsigned long cpsr)
{
int ret = arm_check_condition(cc << 28, cpsr);
@@ -1196,6 +1191,13 @@ static void setup_test_context(struct pt_regs *regs)
regs->uregs[arg->reg] =
(unsigned long)current_stack + arg->val;
memory_needs_checking = true;
+ /*
+ * Test memory at an address below SP is in danger of
+ * being altered by an interrupt occurring and pushing
+ * data onto the stack. Disable interrupts to stop this.
+ */
+ if (arg->reg == 13)
+ regs->ARM_cpsr |= PSR_I_BIT;
break;
}
case ARG_TYPE_MEM: {
@@ -1264,14 +1266,26 @@ test_case_pre_handler(struct kprobe *p, struct pt_regs *regs)
static int __kprobes
test_after_pre_handler(struct kprobe *p, struct pt_regs *regs)
{
+ struct test_arg *args;
+
if (container_of(p, struct test_probe, kprobe)->hit == test_instance)
return 0; /* Already run for this test instance */
result_regs = *regs;
+
+ /* Mask out results which are indeterminate */
result_regs.ARM_cpsr &= ~PSR_IGNORE_BITS;
+ for (args = current_args; args[0].type != ARG_TYPE_END; ++args)
+ if (args[0].type == ARG_TYPE_REG_MASKED) {
+ struct test_arg_regptr *arg =
+ (struct test_arg_regptr *)args;
+ result_regs.uregs[arg->reg] &= arg->val;
+ }
/* Undo any changes done to SP by the test case */
regs->ARM_sp = (unsigned long)current_stack;
+ /* Enable interrupts in case setup_test_context disabled them */
+ regs->ARM_cpsr &= ~PSR_I_BIT;
container_of(p, struct test_probe, kprobe)->hit = test_instance;
return 0;
diff --git a/arch/arm/kernel/kprobes-test.h b/arch/arm/probes/kprobes/test-core.h
index 4430990e90e7..94285203e9f7 100644
--- a/arch/arm/kernel/kprobes-test.h
+++ b/arch/arm/probes/kprobes/test-core.h
@@ -1,5 +1,5 @@
/*
- * arch/arm/kernel/kprobes-test.h
+ * arch/arm/probes/kprobes/test-core.h
*
* Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
*
@@ -45,10 +45,11 @@ extern int kprobe_test_cc_position;
*
*/
-#define ARG_TYPE_END 0
-#define ARG_TYPE_REG 1
-#define ARG_TYPE_PTR 2
-#define ARG_TYPE_MEM 3
+#define ARG_TYPE_END 0
+#define ARG_TYPE_REG 1
+#define ARG_TYPE_PTR 2
+#define ARG_TYPE_MEM 3
+#define ARG_TYPE_REG_MASKED 4
#define ARG_FLAG_UNSUPPORTED 0x01
#define ARG_FLAG_SUPPORTED 0x02
@@ -61,7 +62,7 @@ struct test_arg {
};
struct test_arg_regptr {
- u8 type; /* ARG_TYPE_REG or ARG_TYPE_PTR */
+ u8 type; /* ARG_TYPE_REG or ARG_TYPE_PTR or ARG_TYPE_REG_MASKED */
u8 reg;
u8 _padding[2];
u32 val;
@@ -138,6 +139,12 @@ struct test_arg_end {
".short 0 \n\t" \
".word "#val" \n\t"
+#define TEST_ARG_REG_MASKED(reg, val) \
+ ".byte "__stringify(ARG_TYPE_REG_MASKED)" \n\t" \
+ ".byte "#reg" \n\t" \
+ ".short 0 \n\t" \
+ ".word "#val" \n\t"
+
#define TEST_ARG_END(flags) \
".byte "__stringify(ARG_TYPE_END)" \n\t" \
".byte "TEST_ISA flags" \n\t" \
@@ -395,6 +402,22 @@ struct test_arg_end {
" "codex" \n\t" \
TESTCASE_END
+#define TEST_RMASKED(code1, reg, mask, code2) \
+ TESTCASE_START(code1 #reg code2) \
+ TEST_ARG_REG_MASKED(reg, mask) \
+ TEST_ARG_END("") \
+ TEST_INSTRUCTION(code1 #reg code2) \
+ TESTCASE_END
+
+/*
+ * We ignore the state of the imprecise abort disable flag (CPSR.A) because this
+ * can change randomly as the kernel doesn't take care to preserve or initialise
+ * this across context switches. Also, with Security Extensions, the flag may
+ * not be under control of the kernel; for this reason we ignore the state of
+ * the FIQ disable flag CPSR.F as well.
+ */
+#define PSR_IGNORE_BITS (PSR_A_BIT | PSR_F_BIT)
+
/*
* Macros for defining space directives spread over multiple lines.
diff --git a/arch/arm/kernel/kprobes-test-thumb.c b/arch/arm/probes/kprobes/test-thumb.c
index 844dd10d8593..b683b4517458 100644
--- a/arch/arm/kernel/kprobes-test-thumb.c
+++ b/arch/arm/probes/kprobes/test-thumb.c
@@ -1,5 +1,5 @@
/*
- * arch/arm/kernel/kprobes-test-thumb.c
+ * arch/arm/probes/kprobes/test-thumb.c
*
* Copyright (C) 2011 Jon Medhurst <tixy@yxit.co.uk>.
*
@@ -11,8 +11,9 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <asm/opcodes.h>
+#include <asm/probes.h>
-#include "kprobes-test.h"
+#include "test-core.h"
#define TEST_ISA "16"
@@ -416,6 +417,9 @@ void kprobe_thumb32_test_cases(void)
TEST_RR( "strd r",14,VAL2,", r",12,VAL1,", [sp, #16]!")
TEST_RRP("strd r",1, VAL1,", r",0, VAL2,", [r",7, 24,"], #16")
TEST_RR( "strd r",7, VAL2,", r",8, VAL1,", [sp], #-16")
+ TEST_RRP("strd r",6, VAL1,", r",7, VAL2,", [r",13, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!")
+ TEST_UNSUPPORTED("strd r6, r7, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!")
+ TEST_RRP("strd r",4, VAL1,", r",5, VAL2,", [r",14, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!")
TEST_UNSUPPORTED(__inst_thumb32(0xe9efec04) " @ strd r14, r12, [pc, #16]!")
TEST_UNSUPPORTED(__inst_thumb32(0xe8efec04) " @ strd r14, r12, [pc], #16")
@@ -774,8 +778,8 @@ CONDITION_INSTRUCTIONS(22,
TEST_UNSUPPORTED("subs pc, lr, #4")
- TEST("mrs r0, cpsr")
- TEST("mrs r14, cpsr")
+ TEST_RMASKED("mrs r",0,~PSR_IGNORE_BITS,", cpsr")
+ TEST_RMASKED("mrs r",14,~PSR_IGNORE_BITS,", cpsr")
TEST_UNSUPPORTED(__inst_thumb32(0xf3ef8d00) " @ mrs sp, spsr")
TEST_UNSUPPORTED(__inst_thumb32(0xf3ef8f00) " @ mrs pc, spsr")
TEST_UNSUPPORTED("mrs r0, spsr")
@@ -821,14 +825,22 @@ CONDITION_INSTRUCTIONS(22,
TEST_RP( "str"size" r",14,VAL2,", [r",1, 256, ", #-128]!") \
TEST_RPR("str"size".w r",0, VAL1,", [r",1, 0,", r",2, 4,"]") \
TEST_RPR("str"size" r",14,VAL2,", [r",10,0,", r",11,4,", lsl #1]") \
+ TEST_UNSUPPORTED("str"size" r0, [r13, r1]") \
TEST_R( "str"size".w r",7, VAL1,", [sp, #24]") \
TEST_RP( "str"size".w r",0, VAL2,", [r",0,0, "]") \
+ TEST_RP( "str"size" r",6, VAL1,", [r",13, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"]!") \
+ TEST_UNSUPPORTED("str"size" r6, [r13, #-"__stringify(MAX_STACK_SIZE)"-8]!") \
+ TEST_RP( "str"size" r",4, VAL2,", [r",12, TEST_MEMORY_SIZE,", #-"__stringify(MAX_STACK_SIZE)"-8]!") \
TEST_UNSUPPORTED("str"size"t r0, [r1, #4]")
SINGLE_STORE("b")
SINGLE_STORE("h")
SINGLE_STORE("")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf801000d) " @ strb r0, [r1, r13]")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf821000d) " @ strh r0, [r1, r13]")
+ TEST_UNSUPPORTED(__inst_thumb32(0xf841000d) " @ str r0, [r1, r13]")
+
TEST("str sp, [sp]")
TEST_UNSUPPORTED(__inst_thumb32(0xf8cfe000) " @ str r14, [pc]")
TEST_UNSUPPORTED(__inst_thumb32(0xf8cef000) " @ str pc, [r14]")
diff --git a/arch/arm/probes/uprobes/Makefile b/arch/arm/probes/uprobes/Makefile
new file mode 100644
index 000000000000..e1dc3d0f6d5a
--- /dev/null
+++ b/arch/arm/probes/uprobes/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_UPROBES) += core.o actions-arm.o
diff --git a/arch/arm/kernel/uprobes-arm.c b/arch/arm/probes/uprobes/actions-arm.c
index d3b655ff17da..76eb44972ebe 100644
--- a/arch/arm/kernel/uprobes-arm.c
+++ b/arch/arm/probes/uprobes/actions-arm.c
@@ -13,9 +13,9 @@
#include <linux/uprobes.h>
#include <linux/module.h>
-#include "probes.h"
-#include "probes-arm.h"
-#include "uprobes.h"
+#include "../decode.h"
+#include "../decode-arm.h"
+#include "core.h"
static int uprobes_substitute_pc(unsigned long *pinsn, u32 oregs)
{
@@ -195,8 +195,6 @@ uprobe_decode_ldmstm(probes_opcode_t insn,
}
const union decode_action uprobes_probes_actions[] = {
- [PROBES_EMULATE_NONE] = {.handler = probes_simulate_nop},
- [PROBES_SIMULATE_NOP] = {.handler = probes_simulate_nop},
[PROBES_PRELOAD_IMM] = {.handler = probes_simulate_nop},
[PROBES_PRELOAD_REG] = {.handler = probes_simulate_nop},
[PROBES_BRANCH_IMM] = {.handler = simulate_blx1},
diff --git a/arch/arm/kernel/uprobes.c b/arch/arm/probes/uprobes/core.c
index 56adf9c1fde0..d1329f1ba4e4 100644
--- a/arch/arm/kernel/uprobes.c
+++ b/arch/arm/probes/uprobes/core.c
@@ -17,9 +17,9 @@
#include <asm/opcodes.h>
#include <asm/traps.h>
-#include "probes.h"
-#include "probes-arm.h"
-#include "uprobes.h"
+#include "../decode.h"
+#include "../decode-arm.h"
+#include "core.h"
#define UPROBE_TRAP_NR UINT_MAX
@@ -88,7 +88,7 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm,
auprobe->ixol[1] = __opcode_to_mem_arm(UPROBE_SS_ARM_INSN);
ret = arm_probes_decode_insn(insn, &auprobe->asi, false,
- uprobes_probes_actions);
+ uprobes_probes_actions, NULL);
switch (ret) {
case INSN_REJECTED:
return -EINVAL;
diff --git a/arch/arm/kernel/uprobes.h b/arch/arm/probes/uprobes/core.h
index 1d0c12dfbd03..1d0c12dfbd03 100644
--- a/arch/arm/kernel/uprobes.h
+++ b/arch/arm/probes/uprobes/core.h
diff --git a/arch/arm/xen/enlighten.c b/arch/arm/xen/enlighten.c
index c7ca936ebd99..263a2044c65b 100644
--- a/arch/arm/xen/enlighten.c
+++ b/arch/arm/xen/enlighten.c
@@ -29,10 +29,10 @@
struct start_info _xen_start_info;
struct start_info *xen_start_info = &_xen_start_info;
-EXPORT_SYMBOL_GPL(xen_start_info);
+EXPORT_SYMBOL(xen_start_info);
enum xen_domain_type xen_domain_type = XEN_NATIVE;
-EXPORT_SYMBOL_GPL(xen_domain_type);
+EXPORT_SYMBOL(xen_domain_type);
struct shared_info xen_dummy_shared_info;
struct shared_info *HYPERVISOR_shared_info = (void *)&xen_dummy_shared_info;
diff --git a/arch/arm/xen/mm.c b/arch/arm/xen/mm.c
index 351b24a979d4..793551d15f1d 100644
--- a/arch/arm/xen/mm.c
+++ b/arch/arm/xen/mm.c
@@ -149,7 +149,7 @@ void xen_destroy_contiguous_region(phys_addr_t pstart, unsigned int order)
EXPORT_SYMBOL_GPL(xen_destroy_contiguous_region);
struct dma_map_ops *xen_dma_ops;
-EXPORT_SYMBOL_GPL(xen_dma_ops);
+EXPORT_SYMBOL(xen_dma_ops);
static struct dma_map_ops xen_swiotlb_dma_ops = {
.mapping_error = xen_swiotlb_dma_mapping_error,
diff --git a/arch/arm/xen/p2m.c b/arch/arm/xen/p2m.c
index 054857776254..cb7a14c5cd69 100644
--- a/arch/arm/xen/p2m.c
+++ b/arch/arm/xen/p2m.c
@@ -102,7 +102,7 @@ int set_foreign_p2m_mapping(struct gnttab_map_grant_ref *map_ops,
EXPORT_SYMBOL_GPL(set_foreign_p2m_mapping);
int clear_foreign_p2m_mapping(struct gnttab_unmap_grant_ref *unmap_ops,
- struct gnttab_map_grant_ref *kmap_ops,
+ struct gnttab_unmap_grant_ref *kunmap_ops,
struct page **pages, unsigned int count)
{
int i;